personal_asset
One 44KB Excel File Had Three Tables Crammed Into It
My WeChat backend export looked like a clean spreadsheet. It was actually three tables stitched together sideways, and the error message pointed nowhere near the real problem.
WeChat's official account backend has a stats page that lets you export your reading data for any date range as an .xls file — that's an official feature, meant for operators who want to run their own trend analysis, since the built-in charts only show a handful of fixed dimensions. If you want to slice the numbers your own way, the export file is the only way in. This kind of "export" button shows up in all sorts of backend systems: you click it, the system dumps its database in whatever shape is convenient for it, and what you do with the file afterward is your problem.
I'd written earlier about judging content value by the number of articles that actually got read, not total views. This week I wanted to push that a layer deeper — break the reads down by traffic channel and see which ones were actually doing the work. So I clicked that export button again and got tendency_1780451875_1781402275.xls, 44,032 bytes, one worksheet named New Sheet1, 135 rows by 16 columns. It looked orderly enough. I ran my script and it immediately threw TypeError: '<=' not supported between instances of 'float' and 'datetime.date'. My first thought was "it's barely a hundred rows, how complicated can this be." It turned out to eat up half an afternoon.

My gut instinct was a date-formatting issue — that's the usual cause behind this kind of error, nine times out of ten. I spent a while messing with type conversions, tried three or four different date-parsing approaches, and the error wouldn't budge. Only after opening the raw file and reading it row by row did I realize those 135 rows and 16 columns weren't one clean table at all — they were three completely different data blocks laid out side by side on the same sheet: block one was date, channel, and reads; block two was daily shares, opens-from-article, saves, and posts published; block three was distribution channel, publish date, article title, reads, and share of total. There was no separator between the three blocks, just misaligned blank columns wedged between them. My script assumed "this is one table" and read straight down the columns, so it happily read the headers and blank cells from blocks two and three as if they were dates from block one.
The error talked about formatting, but the real problem was that I'd treated three tables stitched together as if they were one. Once the rows and columns don't line up, the types don't line up either — the error pointed precisely at the symptom and said nothing about the cause.

This isn't a problem unique to the WeChat backend. An "export" button in any backend system hands you whatever format is convenient for that system internally — not a format designed to be friendly to your code. HR systems exporting staff rosters, finance systems exporting statements — they're often built the same way: multi-level headers, merged cells, several data blocks crammed onto one sheet. Whoever built that export was thinking "someone will print this out and read it," not "a script is going to parse this." Tools default to assuming one file equals one table, and most of the time that assumption holds. When it doesn't, the error message will never tell you "this is actually three tables" — it'll just hand you a type error that looks completely unrelated and send you chasing the wrong thing for a while.
The fix itself wasn't hard: pd.to_datetime(..., errors='coerce') turns the misread values into nulls so you can drop them, then aggregate each block separately — five minutes of code. What actually stuck with me is this: I've been doing automation work for years now, and I've hit variations of this exact trap before — once writing fallback logic for a system, once when checking an AI agent that started confidently making up answers when it couldn't find real data. And here I was again, taking a file's surface structure on faith the moment I saw the word "export," instead of opening it up first. If this error had been a little gentler, a little less strange, I probably would have run the numbers straight through that contaminated date column and produced a channel breakdown that looked perfectly normal and was completely wrong, with no idea it had happened. That habit still hasn't fully gone away.
