离线 · 无上传 · 浏览器本地完成Offline · no uploads · runs in the browser
HTML 表格转 Excel——离线、按值取数、不上传HTML table to Excel offline — values kept, no upload
三步的链:`html>json` 从文档里取表格(首行给键名、其余行成对象,`<th>` 与 `<td>` 同等对待,行列都按「只看这张表自己」的作用域读取),`json>csv` 把数组摊成表(列是所有记录键名的并集,缺的键留空格),`csv>xlsx` 写进工作表。产物形态由后两步定:CSV 那一步按**值**而不是显示文本写单元格,所以时间戳与雪花 ID 不会被写成科学计数;最后一步用 `raw: true` 读,SheetJS 的类型推断器碰不到数据,随后只有一道规则把该是数字的格子还回去——十进制形状、`String(Number(x)) === x` 逐字节回得来、有效数字不超过 15 位。16 位以上刻意留在文本,因为表格软件只渲染 15 位有效数字,卡号那一级别的编号变成数字后就被读成 `4.11111111111111E+15`。仍是文本的格子会加公式护栏并把数字格式钉成文本(写出的 `xl/styles.xml` 里那一格就是内置格式号 49)。网页这一侧的既有规则同样跟着走:值在 JSON 那一步全是字符串,链接地址、样式、图片都不进表;两张以上的表交出的是按 `<h2>` 分组的对象,会撞在「只接受数组」那道闸上。全过程在这个标签页里,只有 storage 权限,指向网络的地址一次都不会被请求。A three-step chain: `html>json` lifts tables out of the document (first row names the keys, later rows become objects, `<th>` and `<td>` count alike, rows and cells read inside a “this table only” scope), `json>csv` spreads the array into a table (columns are the union of every record’s keys, and a missing key leaves a blank cell), `csv>xlsx` writes the worksheet. The last two decide the artifact. The CSV step writes cells by **value** rather than display text, so timestamps and snowflake IDs are not written in exponential notation; the final step reads with `raw: true`, keeping SheetJS’s inferrer away from the data, and one rule alone gives the number type back — decimal shape, `String(Number(x)) === x` returning the exact characters, at most 15 significant digits. Sixteen and above deliberately stay text, because a spreadsheet renders 15 significant digits and a card number turned into a number reads back as `4.11111111111111E+15`. Cells still holding text get the formula guard and a pinned text format (that cell carries the built-in format id 49 in the written `xl/styles.xml`). The page side keeps its own rules: values are strings at the JSON step, so link addresses, styling and images contribute nothing, and two or more tables hand over an object grouped by `<h2>` that then meets the “arrays only” gate. All of it inside this tab on the storage permission, with no address the page points at ever fetched.
这条链路怎么走How the route runs
HTMLHTML JSONJSON CSVCSV Excel (.xlsx)Excel (.xlsx)
共 3 步,由扩展的路径搜索自动选出,中间产物不落盘。3 steps, chosen by the extension's own path search; intermediate results never touch the disk.
会保留什么What carries over
- 表头行给列名、每条数据行一行:`<th>` 与 `<td>` 同等对待,用 `<th>` 写表头的规范文档不会整列左移The header row names the columns and each data row becomes one: `<th>` and `<td>` count alike, so a properly written header cannot shift the values
- 数字只在字节能逐字回来时才是数字:`1727000000000` 可求和,`00424`、`1/2`、`2024-01-05` 保持写下的字符A value is a number only when its bytes come back exactly: `1727000000000` is summable while `00424`, `1/2` and `2024-01-05` keep the characters written
- 16 位以上的编号留在文本,并把数字格式钉成文本(写出的那一格是内置格式号 49)Identifiers of 16 digits or more stay text, pinned to a text number format (the written cell carries the built-in format id 49)
- 列取所有记录键名的并集:某行没有的键留空格,多余的单元格被丢,不会让后面几列错位Columns are the union of every record’s keys: a key a row lacks becomes a blank cell and surplus cells are dropped instead of shifting later columns
如实说明的限制What it does not do
- 两张以上的表转不成 Excel:`html>json` 对多张表交出的是以 `<h2>` 文字为键的对象,而 CSV 那一步只接受数组,界面报「JSON 内容必须是包含数据的数组才能转换为 CSV」——请逐张表分开转Two or more tables do not reach Excel: `html>json` gives an object keyed by the document’s `<h2>` text, CSV accepts arrays only, and the interface reports “JSON must be an array containing data to convert to CSV” — convert each table separately
- 表格套在单元格里也算「两张」:内层表的存在会让整批失败,而不是把它的行摊进外层A table nested inside a cell counts as the second one: its presence fails the batch rather than flattening its rows into the outer table
- 值在中间那步全是字符串,靠最后一步的取数规则回头判数字:`1,234.50`、`¥100`、`45%`、`+33` 都不是十进制形状,留在文本Values are strings at the middle step and re-typed only at the last: `1,234.50`, `¥100`, `45%` and `+33` are not decimal-shaped and stay text
- 合并区不展开:被 `colspan` / `rowspan` 覆盖的格子不产生值,那一行的列会左移;链接地址、图片、样式与脚本都不进工作表Merged ranges are not expanded: cells covered by `colspan` / `rowspan` produce no value so that row shifts left, and link addresses, images, styling and scripts contribute nothing to the sheet
- 产物只有一张工作表:这条链一次吃得下一张表,表名沿用读取 CSV 时得到的那一个There is one worksheet: this chain eats a single table at a time, and the sheet keeps whatever name the CSV read produced
实操提示Working with it
- 只想看数据不要工作簿:HTML→CSV 是同一条链的前两步,产物是带 BOM 的文本For the data without a workbook: HTML to CSV is this chain minus the last step, and hands back a BOM’d text file
- 要保留网页排版:直接 HTML→PDF 或 HTML→Word,表格的合并与样式在那边更有落点To keep the page’s layout: go HTML to PDF or Word directly, where merged cells and styling have somewhere to land
- 从 Markdown 出发:Markdown→Excel 走同一条路的第一步是渲染,`##` 小标题会成为分组键Starting from Markdown: Markdown to Excel shares it, with the `##` headings becoming grouping keys
常见问题Questions people actually ask
网页表格里的数字进了 Excel 会是什么?What becomes of the numbers in my page table?
看字符:十进制形状、能逐字节回得来、有效数字不超过 15 位的变成真数字;`00424`、`2024-01-05`、`1/2` 和 16 位编号留在文本并被钉住文本格式。这一族刻意不猜日期与千分位,因为猜就把 `1/2` 变成了某年某月某日。It depends on the characters: decimal-shaped values that round-trip byte for byte with at most 15 significant digits become real numbers, while `00424`, `2024-01-05`, `1/2` and a 16-digit identifier stay text pinned to a text format. This family guesses neither dates nor thousands separators, because guessing is how `1/2` became a calendar day.
为什么我只想要一张表,也要经过 JSON 与 CSV?Why route a table through JSON and CSV at all?
因为写工作簿的那一步只认「已经是一格一格的数据」。把网页取数(DOM 读取)与写表(工作簿容器)分开之后,取数规则只有一处:单元格文字、并集列、值保真——三条路(转 CSV、转 JSON、转 Excel)因此给出一样的判断,不会各自发明一套。Because the workbook writer only understands data that is already cell-shaped. Separating page extraction (DOM reads) from sheet writing leaves one place where the rules live — cell text, union columns, value fidelity — so the CSV, JSON and Excel routes all reach the same verdict instead of each inventing its own.
转的时候会把页面引用的图片和脚本加载吗?Does converting fetch the images and scripts the page references?
不会。读的是文件自己的字节,解析用 DOMParser(只解析、不执行),扩展只有 storage 权限、没有 host 权限,产物里也不会保留那些地址。No. The file’s own bytes are read, parsing goes through DOMParser, which parses without executing, the extension holds the storage permission and no host permission, and the artifact keeps none of those addresses.
不需要账号,也不需要联网:装好扩展后点图标,在新标签页里打开工作台,文件从磁盘直接选。No account and no network: install the extension, click its icon, and the workbench opens in a new tab reading straight off your disk.
从 Chrome 应用商店安装Install from the Chrome Web Store 安装步骤Install steps GitHub 源码Source on GitHub