当前位置: 首页 > news >正文

前端直接生成带格式Excel:字体、行列宽、合并单元格全搞定

本文还有配套的精品资源,点击获取

简介:一套开箱即用的前端Excel导出方案,基于xlsx.js和jQuery实现,能导出带完整样式的.xlsx文件。支持设置中文字体(如微软雅黑)、字号、加粗;自由调整列宽和行高;文字水平居中、垂直居中对齐;按需合并任意行列单元格。资源包里包含可直接运行的excel.html页面、核心库文件(xlsx.js和jquery.min.js)、npm依赖配置(package.和package-lock.),以及基础开发环境配置(.vscode等)。使用前需在项目根目录执行npm install安装依赖,然后通过本地HTTP服务(比如http-server或webpack-dev-server)打开excel.html访问,不能直接双击HTML文件用file://协议运行。业务逻辑代码统一放在js目录下,未命名文件夹可能是额外示例或历史备份,.DS_Store为mac系统自动生成的隐藏文件,可忽略。整个流程不依赖后端,纯前端完成样式化Excel生成。

1. 项目概述:为什么前端直接生成“真·带样式的Excel”一直是个硬骨头?

在日常开发中,我经手过不下二十个导出Excel的需求——从财务报表、课程表到物流清单、设备台账。绝大多数人第一反应是:“后端吐个CSV,前端用<a download>链一下完事”。但只要客户把Excel文件往你面前一推,指着某列文字挤成一团、标题行没加粗、合并的单元格边框发虚、中文显示为方块……你就知道,这种“能打开就行”的方案,在真实业务场景里根本站不住脚。真正让客户点头说“就是这个味儿”的Excel,从来不是数据容器,而是视觉传达工具:它需要微软雅黑12号字撑起专业感,需要列宽精确到0.5字符避免换行错乱,需要标题跨三列并垂直居中对齐,需要合并单元格后依然保留清晰的内外边框。而这些,恰恰是原生xlsx.js最让人挠头的地方——它默认只管数据结构,样式?那是你得自己一层层“砌砖”的苦活。

这套方案之所以值得拿出来细说,是因为它踩准了三个现实痛点:第一,零后端依赖。所有逻辑跑在浏览器里,不走API、不碰服务器,特别适合内部工具、离线系统或权限受限环境;第二,样式控制粒度够细。不是“大概居中”,而是alignment: { horizontal: 'center', vertical: 'center' };不是“差不多宽”,而是width: { wpx: 120 }(像素级列宽)或wch: 25(字符宽度);第三,开箱即用不折腾。你不需要从零搭webpack、配babel、调polyfill,一个npm install加本地服务启动,excel.html里改几行JS就能看到效果。关键词里的“前端导出Excel”“Excel样式控制”“合并单元格”“xlsx.js”“jQuery”,每一个都不是虚词——它们对应着具体可执行的代码段、可验证的CSS类名映射、可调试的单元格坐标计算逻辑。比如,当你要合并A1到C3这9个单元格时,代码里写的不是“合并前三行前三列”,而是{ s: { r: 0, c: 0 }, e: { r: 2, c: 2 } },其中s是start(起始)、e是end(结束),r是row index(行索引从0开始),c是column index(列索引也从0开始)。这种底层坐标思维,才是控制样式的真正钥匙。如果你正被“导出的Excel像记事本”困扰,或者团队里新人总在问“为什么合并单元格后字体变小了”,那接下来的内容,就是你抄作业的完整清单。

2. 核心原理与设计思路:xlsx.js的样式体系到底怎么玩转?

2.1 xlsx.js的“双轨制”样式模型:为什么不能直接写CSS?

很多刚接触xlsx.js的人会本能地想:“既然HTML里能用CSS控制样式,那导出时能不能把.title { font-weight: bold; font-size: 14px; }直接塞进去?”答案是否定的。xlsx.js导出的是二进制.xlsx文件,它遵循的是Office Open XML(OOXML)规范,其样式系统和CSS毫无关系。它采用的是典型的“样式定义 + 单元格引用”双轨模型:先在工作簿的wb.Workbook.Sheets[0].!colswb.Workbook.Sheets[0].!rows里定义列宽、行高;再在wb.Workbook.Sheets[0].!merges里声明合并区域;最后,每个单元格(cell)通过cell.s属性指向一个预定义的样式ID(s: 1),而这个ID对应的完整样式对象,则存放在wb.Workbook.Styles.CellXf数组里。整个过程就像盖楼——CellXf是预制好的钢筋水泥模块(字体、边框、填充色),!cols/!rows是地基尺寸,!merges是承重墙位置,而每个单元格只是贴了个标签,写着“用第1号模块”。

举个实际例子:你想让A1单元格显示“销售汇总”,微软雅黑14号加粗,背景浅蓝,水平垂直居中。在xlsx.js里,你需要三步走:
1.定义样式:创建一个CellStyle对象,包含font: { name: "微软雅黑", sz: 14, bold: true }fill: { fgColor: { rgb: "FFDDEEFF" } }alignment: { horizontal: "center", vertical: "center" }
2.注册样式:调用wb.Workbook.Styles.CellXf.push(styleObj),得到返回的索引值(比如是2);
3.绑定单元格:给ws['A1'].s = { s: 2 }(注意,这里s是小写,代表style ID)。

这个过程看似繁琐,但好处是极致可控——你可以复用同一个样式ID给一百个单元格,修改一处,全局生效;也可以为不同行列单独定制,互不干扰。而jQuery在这里的角色,是帮你快速定位DOM元素、提取表格内容、组织数据结构。比如,你页面上有个<table id="reportTable">,jQuery的$("#reportTable tr").each()能轻松遍历每一行,$(this).find("td,th").each()能逐个读取单元格文本和class属性,再根据class="header-bold"这样的约定,自动匹配到预设的“加粗标题”样式ID。这就是“前端导出Excel”和“纯后端导出”的本质区别:前者把样式逻辑前置到浏览器渲染阶段,用CSS类名作为样式策略的入口,后者则把所有计算甩给服务器。

2.2 中文字体支持的坑:为什么“微软雅黑”在Excel里有时变宋体?

这是国内开发者绕不开的雷区。xlsx.js本身不处理字体渲染,它只是把font.name字段原样写入OOXML。问题出在Excel客户端的字体回退机制上。当你指定name: "微软雅黑",Windows版Excel通常能正确显示,但macOS版Excel或WPS可能因系统未安装该字体,自动降级为“宋体”或“PingFang SC”,导致字号、字间距全乱。实测下来,最稳妥的方案是提供字体备选列表font: { name: ["微软雅黑", "SimSun", "Arial", "sans-serif"], sz: 12, bold: false }。注意,这里name必须是数组,xlsx.js会按顺序尝试,直到找到系统可用的字体。另一个隐藏技巧是:如果业务允许,直接用name: "Arial"+sz: 11,因为Arial在所有平台都存在,且11号Arial的视觉大小接近12号微软雅黑,能规避90%的兼容性问题。我在一个政府项目里就吃过亏——客户用WPS打开,所有标题变成宋体,领导当场质疑“你们做的不是中文系统?”,后来改成双字体数组,一劳永逸。

2.3 合并单元格的坐标陷阱:从0开始的索引 vs 从1开始的Excel界面

新手最容易栽跟头的地方,就是合并单元格的坐标计算。Excel界面上,我们习惯说“A1:C3”,但xlsx.js要求的是{ s: { r: 0, c: 0 }, e: { r: 2, c: 2 } }。这里的r(row)和c(column)都是从0开始的整数索引。A列是c: 0,B列是c: 1,以此类推;第1行是r: 0,第2行是r: 1。所以A1:C3对应的是左上角(0,0)到右下角(2,2)。但如果你的HTML表格有<thead><tbody>,jQuery遍历时$("table tr")拿到的第一行是<tr>,它可能是表头,也可能是数据行,索引容易错位。我的做法是在生成数据前,先用$("table thead th").length算出表头列数,再用$("table tbody tr").length算出数据行数,最后构建一个二维数组data = [[], [], []],确保data[0][0]永远对应Excel的A1单元格。这样,合并操作就变成了纯粹的数组坐标运算,比如合并标题行(第0行,第0列到第2列),直接写{ s: { r: 0, c: 0 }, e: { r: 0, c: 2 } },毫无歧义。

3. 实操细节解析:从HTML表格到带样式的.xlsx,每一步都在填坑

3.1 目录结构与依赖管理:为什么package.json里只有devDependencies?

资源包里的package.json看起来有点“寒酸”——没有dependencies,只有devDependencies,比如"http-server": "^14.1.1"。这是因为整个方案是纯前端静态工程xlsx.jsjquery.min.js都是直接引入HTML的CDN或本地JS文件,不走npm import。package.json存在的唯一目的,就是让你用npm install一键装好本地开发服务器,省去手动下载http-server的麻烦。package-lock.json则锁定了http-server的精确版本,避免不同机器上npm install装出不同行为。至于.vscode文件夹,它存的是VS Code编辑器的配置,比如settings.json里预设了"editor.tabSize": 2"files.exclude"忽略.DS_Store,这对团队协作很实用——新同事拉下代码,打开VS Code,缩进和文件过滤就自动对齐了。那个神秘的6H1wiznO4M5EOqCQUFVF-master-0fb5918589885a4cc7a3bdcb3b9436fc426ab60b文件夹,其实是Git克隆时的临时缓存,可以安全删除;.DS_Store是macOS自动生成的文件夹元数据,Windows用户看不到,Linux用户也用不到,gitignore里已经把它屏蔽了,完全不用理会。

3.2 excel.html的核心骨架:一个最小可行的导出入口

打开excel.html,你会发现它异常简洁:没有复杂的框架,没有Vue或React的模板语法,就是一个标准的HTML5文档。核心结构就三块:
-<table id="exportTable">:这是你的数据源,所有要导出的内容都放在这里。我建议用语义化标签,<thead>放标题行,<tbody>放数据行,<tfoot>放汇总行(如果有)。每一列的<th><td>可以加class,比如class="text-center font-bold",后面JS会根据这些class匹配样式;
-<button id="exportBtn">导出Excel</button>:触发按钮,绑定点击事件;
-<script src="jquery.min.js"></script><script src="xlsx.js"></script>:两个核心库,顺序不能错,jQuery必须在xlsx.js之前加载。

关键点在于,这个HTML文件不包含任何业务逻辑。所有JS代码都放在js/目录下,比如export.js。这样做有两个好处:一是HTML保持纯净,便于UI设计师调整样式;二是JS逻辑可复用,同一个export.js可以被多个HTML页面引用。我在一个电商后台里就用了这招——商品列表页、订单明细页、库存盘点页,都用同一个export.js,只是传入不同的tableId参数,大大减少了维护成本。

3.3 js/export.js详解:如何把jQuery选中的DOM变成Excel对象

js/export.js是整个方案的心脏。它的工作流非常清晰:
1.读取DOM数据$("#exportTable tr").each(function(rowIndex) { ... })遍历每一行,$(this).find("td,th").each(function(colIndex) { ... })遍历每一列,把文本内容、class属性、rowspan/colspan属性都提取出来,存进一个二维数组sheetData
2.识别合并单元格:这是最难的部分。rowspan="2"意味着当前单元格向下跨1行(因为自身占1行),所以合并区域是{ s: { r: rowIndex, c: colIndex }, e: { r: rowIndex + 1, c: colIndex } }。同理,colspan="3"是向右跨2列。代码里会用一个mergeCells = []数组收集所有合并对象,最后统一塞进ws['!merges']
3.设置列宽与行高ws['!cols']是一个对象数组,ws['!cols'][0] = { wpx: 150 }表示A列宽150像素;ws['!rows']同理,ws['!rows'][0] = { hpx: 30 }表示第1行高30像素。我通常会先用jQuery读取$("#exportTable th").eq(0).width()获取DOM中A列的实际像素宽度,再乘以1.2作为Excel列宽,这样能保证导出后和网页显示基本一致;
4.应用样式:遍历sheetData,对每个单元格检查class,比如遇到class="header",就给它分配预定义的样式ID1(对应加粗、居中、背景色);遇到class="number",就分配ID2(对应右对齐、千分位);
5.生成并下载:调用XLSX.writeFile(wb, "report.xlsx"),浏览器就会弹出下载对话框。

这里有个重要技巧:xlsx.jswriteFile方法在Safari浏览器里有时会失败,因为Safari对Blob的处理更严格。解决方案是在调用前加一句if (typeof window.navigator.msSaveBlob !== 'undefined') { ... }做兼容判断,不过本方案已内置了这个补丁,你无需操心。

4. 完整实操流程:手把手带你导出第一个带样式的Excel

4.1 环境准备与首次运行:三分钟搞定本地服务

第一步,确保你电脑上装了Node.js(推荐v18.x LTS版本)。打开终端(macOS/Linux)或命令提示符(Windows),进入资源包根目录:

cd /path/to/your/downloaded/package

执行安装命令:

npm install

这会根据package.json安装http-server。安装完成后,启动本地服务:

npx http-server -p 8080

终端会输出类似Starting up http-server, serving .Available on: http://127.0.0.1:8080的信息。现在,打开浏览器,访问http://localhost:8080/excel.html。注意,绝对不要双击excel.htmlfile://协议打开——因为现代浏览器出于安全限制,file://协议下无法执行XMLHttpRequest,而xlsx.js的某些功能(如读取本地文件)依赖于此,会导致脚本报错。http-server提供的http://协议则完全没问题。

4.2 修改示例表格:从“Hello World”到真实业务数据

打开excel.html,找到<table id="exportTable">部分。默认示例是一个3×3的简单表格。现在,我们把它升级为一个真实的“月度销售报表”:

<table id="exportTable"> <thead> <tr> <th class="header" colspan="4">2024年6月销售汇总报表</th> </tr> <tr> <th class="header">产品名称</th> <th class="header">销量(件)</th> <th class="header">单价(元)</th> <th class="header">销售额(元)</th> </tr> </thead> <tbody> <tr> <td>无线蓝牙耳机</td> <td class="number">1250</td> <td class="number">199.00</td> <td class="number">248750.00</td> </tr> <tr> <td>智能手表</td> <td class="number">890</td> <td class="number">899.00</td> <td class="number">800110.00</td> </tr> </tbody> <tfoot> <tr> <td class="footer" colspan="3">总计</td> <td class="number footer">1048860.00</td> </tr> </tfoot> </table>

关键变化有三点:一是<thead>里用colspan="4"合并了标题行;二是给数字列加了class="number",方便JS识别右对齐;三是<tfoot>里加了汇总行,并用class="footer"标记。保存文件后,刷新浏览器,点击“导出Excel”按钮。你会看到生成的Excel里,“2024年6月销售汇总报表”横跨四列并居中,“总计”行同样合并且背景色不同,所有数字都右对齐,小数点对齐——这就是样式控制的威力。

4.3 自定义样式配置:在js/export.js里添加你的专属样式

打开js/export.js,找到const styles = { ... }对象。默认它定义了headernumberfooter三种样式。现在,我们为“产品名称”列添加一个特殊样式——深灰色背景、白色文字、加粗:

// 在styles对象里新增 product: { font: { name: ["微软雅黑", "SimSun"], sz: 12, bold: true }, fill: { fgColor: { rgb: "FF444444" } }, // 深灰背景 fontColor: { rgb: "FFFFFFFF" }, // 白色文字 alignment: { horizontal: "left", vertical: "center" } }

然后,在读取单元格的循环里,加入判断逻辑:

// 在 $(this).find("td,th").each(...) 循环内 const $cell = $(this); const cellClass = $cell.attr('class') || ''; if (cellClass.includes('product')) { cell.s = { s: getStyleId('product') }; // getStyleId是封装好的函数,返回样式ID }

保存后刷新页面,给“无线蓝牙耳机”和“智能手表”这两行的<td>加上class="product",再次导出,就能看到深灰底白字的效果了。这个模式可以无限扩展:status-success(绿色背景)、status-error(红色背景)、highlight(黄色高亮)……所有样式都由你定义,自由组合。

4.4 列宽与行高的精准控制:像素级 vs 字符级的抉择

xlsx.js提供了两种列宽单位:wpx(像素)和wch(字符)。wpx: 150表示列宽150像素,适合固定布局;wch: 20表示按20个字符宽度计算,适合内容长度不确定的场景。我的经验是:标题行用wch,数据行用wpx。因为标题文字通常较短且固定,wch: 15足够;而数据行可能有长文本(如产品描述),用wpx能保证最小宽度,避免内容被截断。在js/export.js里,设置列宽的代码通常是:

// A列(产品名称)设为180像素 ws['!cols'][0] = { wpx: 180 }; // B、C、D列(数字)设为120像素 for (let i = 1; i <= 3; i++) { ws['!cols'][i] = { wpx: 120 }; } // 第1行(大标题)设为40像素高 ws['!rows'][0] = { hpx: 40 }; // 第2行(小标题)设为30像素高 ws['!rows'][1] = { hpx: 30 };

行高同理,hpx是像素,hpt是磅(1pt=1.33px)。测试时,我习惯先用hpx: 30,导出后在Excel里微调,再反推回代码值,这样最准。

5. 常见问题与排查技巧实录:那些让我熬夜改了三遍的Bug

5.1 问题速查表:高频报错与一招解决

问题现象可能原因解决方案
点击导出按钮无反应,控制台报XLSX is not definedxlsx.js未正确加载或路径错误检查excel.html<script src="xlsx.js">src路径是否正确,确认文件在根目录;用浏览器开发者工具Network标签页看xlsx.js是否返回200
导出的Excel打开后提示“文件格式错误”或“内容有问题”ws['!merges']数组里有重复或越界坐标js/export.js里加console.log(mergeCells),检查每个合并对象的s.r/s.c/e.r/e.c是否为非负整数,且s.r <= e.rs.c <= e.c;删除mergeCellse.r大于总行数的项
中文显示为方块或乱码font.name只写了单个字体,且系统未安装font.name改为数组,如["微软雅黑", "SimSun", "Arial"];或改用通用字体"Arial"
合并单元格后,被覆盖的单元格内容消失合并区域内的单元格仍有数据,但Excel只显示左上角单元格内容确保合并区域内,只有左上角单元格(s.r, s.c)有v值(内容),其他单元格的v值必须为undefinednull;在JS里给ws[cellAddress].v = undefined
数字列导出后变成科学计数法(如1250显示为1.25E+3)Excel自动将长数字识别为数值并格式化给数字单元格加z: "@"(文本格式),如cell.z = "@";或在数字前加单引号',如'1250

5.2 实操避坑心得:血泪总结的5条铁律

提示:这些全是我在三个项目里踩过的坑,写在这里,省得你再交学费。

铁律一:永远先清空ws['!merges']再重新赋值
新手常犯的错误是,在每次导出前,用push()ws['!merges']里追加新合并项,却不清理旧的。结果第一次导出正常,第二次导出就出现“合并区域重叠”的Excel警告。正确做法是:在生成新工作表前,先执行ws['!merges'] = [],再push本次需要的合并项。就像做饭前先洗锅,再放油。

铁律二:rowspan/colspan的DOM属性值是字符串,不是数字
jQuery的$(this).attr('rowspan')返回的是字符串"2",不是数字2。如果你直接用它计算e.r = s.r + rowspan,结果会是0 + "2" = "02"(字符串拼接),导致坐标错乱。务必用parseInt($(this).attr('rowspan'), 10)转成整数。

铁律三:xlsx.jswriteFile不支持IE11,但write可以
如果你的客户还在用IE11(别笑,真有),XLSX.writeFile(wb, "file.xlsx")会报错。解决方案是改用XLSX.write(wb, { type: 'blob', bookType: 'xlsx' })生成Blob,再用URL.createObjectURL(blob)创建下载链接。本方案的export.js里已封装了downloadBlob函数,直接调用即可。

铁律四:!cols!rows的索引必须连续,不能跳号
ws['!cols'][0] = { wpx: 100 }; ws['!cols'][2] = { wpx: 200 };这样写,A列和C列有宽度,B列会默认极窄(约8像素),内容全挤在一起。必须保证ws['!cols'][i]i=0开始连续定义,中间不能留空。可以用Array.from({ length: 10 }, () => ({ wpx: 120 }))生成10列默认宽度。

铁律五:字体大小sz的单位是“半磅”,不是“磅”
sz: 24表示12磅(因为1磅=2半磅),也就是常规的12号字。如果你想要14号字,应该写sz: 28。这个反直觉的设计,让无数人调了半小时才发现字号不对。记住口诀:“想要几号字,就写几乘二”。

6. 进阶扩展与实战建议:让这套方案陪你走得更远

6.1 从jQuery迁移到原生JS:去掉jQuery依赖的轻量版

虽然jQuery让DOM操作变得简单,但如果你追求极致轻量(比如嵌入到微信小程序WebView或老旧系统),完全可以去掉它。核心替换如下:
-$("#exportTable tr")document.querySelectorAll("#exportTable tr")
-$(this).find("td,th")this.querySelectorAll("td,th")
-$(this).attr('class')this.getAttribute('class')
-$(this).text()this.textContent

整个export.js去掉jQuery后,体积能从8KB降到3KB。我在一个物联网设备的本地管理页面里就这么干过——设备内存只有64MB,多一个jQuery就是多一份负担。迁移时唯一要注意的是,原生querySelectorAll返回的是NodeList,不是数组,遍历时要用Array.from(nodeList).forEach(...)for (const el of nodeList) {...}

6.2 支持多Sheet导出:一个Excel文件,多个工作表

xlsx.js天生支持多Sheet。在js/export.js里,wb.Workbook.Sheets是一个数组,wb.Workbook.Sheets[0]是第一个Sheet。要加第二个Sheet,只需:

const ws2 = XLSX.utils.aoa_to_sheet([["Sheet2数据"]]); ws2['!cols'] = [{ wpx: 150 }]; wb.Workbook.Sheets.push(ws2); // 注意,这里是push到Sheets数组 wb.Workbook.SheetNames.push("销售明细"); // SheetNames也要同步加名字

这样,导出的Excel就会有两个Tab:“Sheet1”和“销售明细”。我常用这个功能做“主表+明细表”:主表是汇总数据,明细表是原始记录,客户点开就能钻取。

6.3 与现有框架集成:Vue/React项目里怎么用?

如果你的项目是Vue CLI或Create React App搭建的,不必推翻重来。把xlsx.jsjquery.min.js(如果还用jQuery)放进public/目录,然后在组件的methods里:

// Vue组件里 exportExcel() { const table = document.getElementById('exportTable'); const wb = XLSX.utils.book_new(); const ws = XLSX.utils.table_to_sheet(table); // xlsx.js自带的table转sheet XLSX.utils.book_append_sheet(wb, ws, "数据"); XLSX.writeFile(wb, "report.xlsx"); }

注意,table_to_sheet会自动处理rowspan/colspan,但不会处理样式。所以,如果你需要字体、颜色等,还是得走手动构建ws的老路。这也是为什么本方案坚持手动构建——为了100%的样式控制权。

6.4 性能优化:万行数据导出不卡顿的秘诀

当表格行数超过5000行时,xlsx.jswriteFile会明显变慢,浏览器可能假死。我的优化方案是“分批生成 + Blob流式下载”:
1. 把大数据拆成每1000行一个ws
2. 用XLSX.write(wb, { type: 'array' })生成Uint8Array
3. 用new Blob([uint8Array], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })创建Blob;
4. 最后用URL.createObjectURL(blob)触发下载。

这个方案能把10万行导出时间从30秒压到8秒以内。代码稍复杂,但本方案的js/performance.js里已有完整实现,直接复制粘贴即可。

最后再分享一个小技巧:如果你的Excel需要插入公司Logo,xlsx.js本身不支持图片,但可以用XLSX.utils.encode_image把Base64图片转成OOXML格式,再注入到ws['A1'].v里。不过这属于高阶玩法,日常需求用不到,就不展开说了。这套方案的核心价值,从来不是炫技,而是让每个前端工程师,都能在十分钟内,交付一份让客户挑不出毛病的Excel——字体、行高、合并、对齐,全部拿捏。它不追求最新技术栈,只解决最痛的业务问题。当你下次再听到“导出个Excel吧”,心里能稳稳地说一句:“好,马上给你。” 那就是这套方案,真正落地的声音。

本文还有配套的精品资源,点击获取

简介:一套开箱即用的前端Excel导出方案,基于xlsx.js和jQuery实现,能导出带完整样式的.xlsx文件。支持设置中文字体(如微软雅黑)、字号、加粗;自由调整列宽和行高;文字水平居中、垂直居中对齐;按需合并任意行列单元格。资源包里包含可直接运行的excel.html页面、核心库文件(xlsx.js和jquery.min.js)、npm依赖配置(package.和package-lock.),以及基础开发环境配置(.vscode等)。使用前需在项目根目录执行npm install安装依赖,然后通过本地HTTP服务(比如http-server或webpack-dev-server)打开excel.html访问,不能直接双击HTML文件用file://协议运行。业务逻辑代码统一放在js目录下,未命名文件夹可能是额外示例或历史备份,.DS_Store为mac系统自动生成的隐藏文件,可忽略。整个流程不依赖后端,纯前端完成样式化Excel生成。


本文还有配套的精品资源,点击获取

http://www.zskr.cn/news/1484997.html

相关文章:

  • Swing应用动态换肤怎么玩?基于FlatLaf实现用户自定义主题切换(含圆角、颜色自定义)
  • MyBatis-Plus Mapper 扫描完全指南
  • engGNN双图神经网络在阿尔茨海默病基因分析中的应用
  • 嵌入式网络调试避坑实录:W5500驱动集成中SPI片选(CS)与中断的那些‘坑’
  • 联盛德W806驱动ST7567液晶屏避坑指南:硬件SPI配置、内存偏移处理与对比度调校
  • C++特殊类设计(详细介绍)
  • 2026年众智商学院中级经济师上班族晚间班期费用资料怎么核对?官网400冯老师 - 众智商学院官方
  • MATLAB实现GNSS+IMU组合导航仿真:EKF融合算法全流程可运行代码包
  • 央视连发三条专题!济南AI模型工厂:75道工序流水线量产,一年“造“出1000+模型
  • 从自动驾驶到电机控制:聊聊卡尔曼滤波这位‘跨界大神’的降维应用
  • 华硕笔记本性能管理神器:G-Helper轻量级控制工具完全指南
  • 2026年众智商学院PMP官网咨询入口:怎么报名和怎么选班期领取资料 - 众智商学院官方
  • 从0到1构建生产级RAG系统:架构、实战与避坑指南
  • 2026出圈!5款AI论文写作软件亲测,摆脱无效加班,初稿质量效率翻倍
  • 手把手教你配置TMS320F28335的SPI模块(含FIFO模式与自测代码)
  • Windows服务器可用的ASP电视直播站源码,含播放页与后台管理全套文件
  • Matlab图像分类教学包:20+生活场景图+全流程可运行代码(含视频帧处理)
  • 农产品全链条溯源系统:SpringBoot微服务+Fabric区块链实现从田间到餐桌的可信追踪
  • Jupyter Lab 3.x 用户注意:升级后IProgress报错的完整修复指南(含ipywidgets兼容性详解)
  • 单流检测:KCC 在独享链路时的行为切换
  • 轻松拿下OpenResty神器
  • SAP MM配置避坑指南:BP转供应商时,为什么必须勾选‘相同号码’?一个真实案例引发的思考
  • Streamlit:用 Python 快速构建数据应用
  • TDOA无源定位Chan算法MATLAB实现:含主程序、结果图与参数可调接口
  • 人力资源AI应用落地
  • 别再到处找图标了!手把手教你用Bootstrap Icons 1.7.2搞定前端项目
  • 遗传算法Python实战:N皇后问题从原理到稳定收敛
  • 多维聚合中的数据操纵:从GROUP BY到OLAP立方体的四次空间变换
  • 解决高并发多模态任务下的“状态漂移”:基于分布式任务管理的状态收敛实录
  • 信用分配的范式跃迁:当稀疏奖励遭遇百万 Token 长廊