☰
浏览器打印实现html转PDF:中文图片表格全支持
2026/10/9 15:31:56 网站建设 项目流程

简介:面对浏览器打印时排版错乱、中文乱码、图片丢失等常见痛点,这套完整源码提供基于jspdf与html2canvas的轻量化解决方案,无需任何浏览器插件即可将任意HTML页面高质量导出为PDF,尤其适合中文业务系统。压缩包共10个文件,大小仅1.76MB,核心包括JavaScript库、两个可直接运行的示例HTML页面、中文字体、字体转换工具及CSS样式,各模块用途清晰,便于二次开发。资源内置了转换好的中文字体,规避中文乱码问题,同时附带字体转换工具,允许开发者按需生成其他字体,仅需6行代码即可实现所见即所得的原样矢量输出,完整支持文本、图片与表格元素。已有528人学习下载,适合前端开发者、运维人员或需要批量生成报告、合同、票据等场景的工程师快速落地PDF导出功能。

1. 为什么说 html 转 pdf 文件下载,最合理的方案是浏览器打印

搜 html 转 pdf 文件下载,常见思路是装打印插件、引一个 JS 绘图库、或者写个后端接口生成文件。我这些年做过的模拟项目X里,凡是走这三条的,基本都会在两个字上翻车:乱码和排版。中文变成方块、表格跨页被拦腰切断、图片加载成空白。换到浏览器自带的打印能力之后,这些问题一次性消失了大半:chrome、edge、safari 早就内置了 PDF 输出,你点一下按钮,选“另存为 PDF”,一份完整的中文文档就落地了。

这个方向叫 web 页面 pdf 打印也好,叫 html 转 pdf 完整源码也好,核心都是同一件事:让浏览器排版引擎把页面当纸张渲染。它不需要任何插件,系统字体负责中文,网络图片自己加载,表格交给打印引擎分页,三样全支持。下面的内容从最小实现写起,逐步覆盖中文图片表格的处理、PDF 文件名控制以及常见的坑。适合那些不想引入重型依赖、又必须支持中文与图片表格的下载场景。

2. 最小可跑的实现:window.print() 加 @media print,一个函数搞定下载

2.1 为什么主线是浏览器打印,而不是 JS 绘图库、插件或后端服务

先回答一个经常被追问的问题:市面上明明有专门生成 PDF 的 JS 库,为什么还要绕回打印?原因很现实。那些库的本质是在 canvas 里把 DOM 重新画一遍,画出来的文字是矢量还是图片,取决于字体是否嵌入成功。中文字体动辄几 MB,很多库为了体积默认不嵌入完整字形,于是导出后中文要么变方块,要么变成图片格式又糊又大。

插件方案更尴尬。装了插件的人电脑上有按钮,换一台电脑没有就白搭,你还要专门写一堆兼容逻辑。至于后端方案,不是说不行,而是要起服务、管任务队列、处理文件存储,为了导一份报告搭这么大架子,成本没必要的。浏览器打印这条路,用的就是用户自己电脑上的渲染引擎,所见即所得,不需要任何额外运行时。

所以我一般给出的第一版实现,永远是这个最小骨架。它只有一段 HTML、一个按钮、两条 CSS 规则和一个 JS 函数,把这份代码存成一个 .html 文件双击打开,就是完整可用的 html 转 pdf 下载页面:

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>模拟项目X-月度报告</title> <style> .no-print { display: block; } @media print { .no-print { display: none !important; } .report-body { width: 100%; } } </style> </head> <body> <!-- 打印按钮只在屏幕上显示 --> <button class="no-print" onclick="downloadPdf()">下载 PDF</button> <!-- 需要导出的内容 --> <div class="report-body"> <h1>月度数据报告</h1> <p>这是一段支持中文、图片和表格的正文内容。</p> </div> <script> function downloadPdf() { // 打印前临时修改 document.title,很多浏览器会用它作为 PDF 默认文件名 const oldTitle = document.title; document.title = '模拟项目X-月度报告.pdf'; // 触发系统打印对话框,用户选择“另存为 PDF”即完成下载 window.print(); // 打印对话框关闭后恢复原标题,避免影响页面显示 document.title = oldTitle; } </script> </body> </html>

这段代码的逻辑说明:按钮的 onclick 绑定 downloadPdf(),函数里只做三件事——保存旧标题、改 document.title、调用 window.print()。print() 是阻塞调用,会停下来打开打印对话框,用户选好“另存为 PDF”并点击保存后,文件由浏览器直接写出。页面拿不到保存路径,也不需要后端参与写文件。

参数说明:@media print 里 .no-print 负责隐藏屏幕上才需要的按钮,避免按钮印到纸上;.report-body 不设固定高度,让内容按自然文档流分页。这个最小版本没处理懒加载图片和表格跨页,那属于第三章的内容。如果你要在这个基础上扩展,只要保证一个原则:屏幕样式和打印样式用同一套 DOM,打印样式只做覆盖,不要复制内容。

2.2 打印事件的两个时机:beforeprint 和 afterprint

真实业务不会像最小示例那样简单,页面上有图表、有滚动加载的列表、有临时需要塞进 PDF 里的信息。浏览器提供了两个非常实用的生命周期事件:beforeprint 和 afterprint,桌面端 Chrome、Edge、Firefox、Safari 都支持。beforeprint 在打印对话框打开前触发,是最后一次“整理现场”的机会;afterprint 在对话框关闭后触发,用来清理现场。

我一般会在 beforeprint 里做三件事:把还没加载完的资源等一等、把要写进 PDF 的临时信息填进 DOM、把 document.title 改成最终文件名。在 afterprint 里则反向操作:恢复 title、删掉临时节点、复位滚动位置。有一个细节要注意:打印时会触发窗口 resize,不要在 resize 监听里做二次渲染,容易造成死循环。

// 页面初始化时统一挂载打印生命周期 let originalTitle = ''; window.addEventListener('beforeprint', () => { // 记录原标题,打印结束要恢复 originalTitle = document.title; // 设置 PDF 默认文件名,Windows 不友好的字符会被过滤 document.title = buildPdfFilename('模拟项目X-月度报告', '2025-06'); // 把打印版专属的页脚信息填进 DOM,屏幕上不显示 const footer = document.getElementById('print-footer'); if (footer) { footer.textContent = new Date().toLocaleDateString('zh-CN'); } }); window.addEventListener('afterprint', () => { // 还原标题,避免页签一直显示成文件名 document.title = originalTitle; // 清空临时页脚 const footer = document.getElementById('print-footer'); if (footer) { footer.textContent = ''; } }); // 过滤 Windows 文件系统非法字符 function buildPdfFilename(prefix, dateStr) { const safe = `${prefix}_${dateStr}`.replace(/[\\/:*?"<>|]/g, '_'); return `${safe}.pdf`; }

这段代码的逻辑说明:把 title 的写入放在 beforeprint 里,比放在按钮点击函数里更可靠。因为用户可能用 Ctrl+P 快捷键直接调出打印,不经过你的按钮,beforeprint 照样能兜住。print-footer 是一个只存在于打印样式里的节点,屏幕上 display: none,打印时显示,用来放日期、页码这类“只在纸上出现”的信息。

参数说明:originalTitle 用模块级变量保存,避免在 afterprint 里取不到旧值。buildPdfFilename 里的正则过滤了 Windows 文件名非法字符,防止用户保存时系统弹错。dateStr 传什么格式由业务决定,示例里传的是年月,如果想精确到天,就传 YYYY-MM-DD。这里点的目标是:文件名是用户在保存对话框里最终确认的,我们只能控制默认值,不能强制指定。

2.3 @page 规则:A4 尺寸、页边距与打印背景色

很多导出 PDF 自带一行网址和日期,看起来像水印,其实是打印对话框里“页眉和页脚”开关导致的系统输出。CSS 里的 @page 规则可以控制纸张大小和内容边距,但没有能力直接关掉系统页眉。这里要分清两个层次:@page 管理的是“纸张和内容区”,页眉页脚是对话框里的独立开关,两者互相影响。

@page { /* 纸张尺寸:A4 纵向 */ size: A4 portrait; /* 四边距,单位 mm,贴近打印习惯 */ margin: 14mm 10mm 16mm 10mm; } @media print { body { /* 保留背景色和背景图,否则会被浏览器默认去掉 */ -webkit-print-color-adjust: exact; print-color-adjust: exact; } .no-print { display: none !important; } .report-body { width: 100%; font-size: 12pt; line-height: 1.6; } }

这段 CSS 的逻辑说明:@page 里的 margin 决定内容区在纸上的位置,size 决定纸张类型。print-color-adjust: exact 是给浏览器的一个请求:把 background-color 和 background-image 也输出到 PDF。如果不写,Chrome 默认会把所有背景色当“装饰”去掉,导出的表格只剩下白色底和数据文字,条纹背景全消失。

参数说明:size 还可以写 A4 landscape 做横向签批单,或者 A5 做小册子;margin 不要小于 5mm,打印机的物理边距普遍大于这个值,设太小会被设备裁掉。font-size 在打印时建议调到 12pt 左右,屏幕端的 14px 换算到纸上会偏小。如果正文包含大量表格,考虑把上下边距放宽到 16mm 以上,给分页位置留出喘息空间。

3. 中文、图片、表格三项硬骨头:为什么别人导出的 PDF 会翻车

3.1 中文不乱码:字体栈、字形缺失和文件编码的三层检查

html 转 pdf 翻车,十次里有八次是中文问题,搜索引擎里搜“pdf 图片中文设置”的人特别多。先给结论:浏览器打印方案下,中文渲染走的是系统字体引擎,只要操作系统装了中文字体,就不会缺字形。真正导致乱码的,通常是下面三件事里的一件:页面用了远程 web font 但打印时字体还没加载完、JS 绘图方案没有把中文字体嵌入导出文件、HTML 文件本身编码声明写错了。

第一层是字体栈。打印样式里把 font-family 写全,优先使用系统中文字体,避免每个设备因为缺字体退回不同的默认渲染。第二层是预加载。如果页面确实用了 @font-face 的 icon 字体或品牌字体,在 beforeprint 里用 document.fonts.ready 等字体加载完成再调 print()。第三层是编码,HTML 文件开头必须写 ,并且文件实际保存编码要跟声明一致,否则所有中文在解析阶段就已经错了,再好的打印样式也救不回来。

@media print { body { /* 中文优先使用系统的三套中文字体,按操作系统命中 */ font-family: "PingFang SC", "微软雅黑", "Noto Sans CJK SC", sans-serif; /* 中文标点按中文排版习惯收缩,避免标点悬挂行首 */ line-break: strict; word-break: break-word; } }

逻辑说明:PingFang SC 对应 Mac,微软雅黑对应 Windows,Noto Sans CJK SC 对应 Linux 和 Android 场景。浏览器会从左到右逐个检测,当前系统有哪个用哪个,都没有就回退到 sans-serif。这个顺序保证了不同设备导出 PDF 时的中文字形稳定一致。

参数说明:line-break: strict 是中文排版规则,句号、逗号、引号会按中文习惯处理,不会孤零零出现在行首。word-break: break-word 防止长英文或 URL 把表格列撑破。如果读者反馈“在 Windows 上导出是宋体,在 Mac 上是苹方”,那不是错误,是字体栈依次命中导致的正常差异,PDF 打开效果不会缺字。

3.2 图片不丢失:懒加载回填、完整地址与 background-image 的坑

图片在 PDF 里消失,多半是三种原因:图片地址是相对路径或懒加载未触发、background-image 被打印样式禁用、图片还没加载完打印就开始了。现在主流网站都用懒加载,img 标签的真实地址放在>// 打印前统一处理图片:回填懒加载地址并等待解码 async function prepareImages(root = document) { // 1. 回填所有懒加载图片的真实地址 root.querySelectorAll('img[data-src]').forEach((img) => { if (img.dataset.src && !img.src) { img.src = img.dataset.src; } }); // 2. 过滤出需要等待的网络图片 const images = Array.from(root.querySelectorAll('img')) .filter((img) => img.src && img.src.startsWith('http')); // 3. 并发等待解码,单张失败不阻断全局 await Promise.all( images.map((img) => img.decode().catch(() => console.warn('image decode failed:', img.src)) ) ); }

逻辑说明:这个函数解决“图片显示一半”和“图片位置空白”两个典型故障。第一步处理懒加载组件留下的>@media print { table { /* 合并边框,避免分页处出现双重边框 */ border-collapse: collapse; width: 100%; page-break-inside: auto; } thead { /* 表头在每一页顶部都重复打印 */ display: table-header-group; } tr { /* 禁止一行被拆到两页 */ break-inside: avoid; page-break-inside: avoid; } td, th { border: 1px solid #333; padding: 6px 8px; vertical-align: top; word-break: break-word; } }

逻辑说明:display: table-header-group 是这一节里最重要的属性,它告诉打印引擎把 thead 当作“跨页重复的表头组”,每页顶部自动重渲一次。tr 的 break-inside: avoid 让一行整体移动到下一页,而不是在页边处劈开。border-collapse 合并相邻边框,避免分页线处出现加粗的边界。

参数说明:page-break-inside: avoid 绝对不能加在 table 上。新手很容易顺手把避断规则加到整表,结果是打印引擎把整张表当做一个整体块,第一页留下一大段空白,表直接挪到第二页。另外,如果表格带 rowspan 或 colspan,部分浏览器分页会变得不稳定,这时最稳的兜底方案是后端或前端按每页 25~30 行手工切片,每个分页包裹一个独立的 table 和 thead,而不是完全依赖打印引擎推算。

4. 把“下载”做实:PDF 文件名、打印对话框参数与多页控制

4.1 文件名怎么控制:document.title 是唯一可靠的抓手

“文件下载”这个词在 html 转 pdf 场景里经常被误解。浏览器打印出来的 PDF,保存对话框里的默认文件名取自页面,改 title 就能控制默认文件名。但打印对话框是浏览器原生窗口,JavaScript 拿不到用户选定的保存路径,也不知道用户是点了保存还是取消。这是浏览器的安全设计,页面脚本不能绕过系统对话框直接写文件到磁盘。</p> <p>所以“下载”落地是两件事:确保默认文件名正确、确保用户操作路径清晰。文件名控制在代码层面就一句话:打印前改 document.title。要注意 Windows 文件系统不允许文件名包含 : * ? " < > | 这些字符,拼文件名时先过滤一遍。有人试过给 window.print() 传参指定文件名,那是无效的,print() 不接收文件名参数。</p> <pre><code class="language-javascript">// 在调用打印前设置默认文件名 function downloadPdf() { const base = '模拟项目X-月度报告'; const safe = `${base}_2025-06`.replace(/[\\/:*?"<>|]/g, '_'); const oldTitle = document.title; document.title = `${safe}.pdf`; window.print(); document.title = oldTitle; } </code></pre> <p>逻辑说明:replace 用正则把 Windows 非法字符统一替换成下划线,避免保存时系统弹错误。document.title 在 print() 调用前写入,浏览器打开打印对话框时已经读取了新标题。afterprint 之后再恢复原标题,防止页签长时间显示成带 .pdf 后缀的文件名。</p> <p>参数说明:如果你在 beforeprint 里已经处理过 title,那就不需要在按钮函数里重复设置,两边选一处维护即可。单页应用里 title 通常由路由管理,直接改 document.title 可能被路由监听覆盖,这时候要走框架提供的 title 管理接口,打印完成再恢复。相比 JS 绘图库能精确控制导出文件名,浏览器方案只能控制默认值,最终文件名由用户在保存对话框里确认,这一点要在需求沟通时讲清楚。</p> <h3>4.2 打印对话框里的选项与 @page 参数对照</h3> <p>打印对话框里有几个选项直接决定 PDF 成品的长相,很多人搞不清它们和 CSS 的关系。我列一张对照表,照着查就行:</p> <table> <thead> <tr> <th>对话框选项</th> <th>作用</th> <th>是否能被 CSS 控制</th> <th>处理方式</th> </tr> </thead> <tbody> <tr> <td>目标打印机</td> <td>选“另存为 PDF”或系统 PDF 打印机</td> <td>不能</td> <td>引导用户在选择列表里选 PDF 输出</td> </tr> <tr> <td>页眉和页脚</td> <td>顶部网址、标题、日期、页码</td> <td>不能</td> <td>提示用户取消勾选</td> </tr> <tr> <td>背景图形</td> <td>是否输出背景色和背景图</td> <td>可以请求,最终由开关决定</td> <td>CSS 加 print-color-adjust: exact</td> </tr> <tr> <td>边距</td> <td>内容与纸边的距离</td> <td>可以,@page margin</td> <td>设 10~16mm,别小于 5mm</td> </tr> <tr> <td>纸张大小</td> <td>A4 / A5 / 横向</td> <td>可以,@page size</td> <td>按业务选 portrait 或 landscape</td> </tr> </tbody> </table> <p>页眉和页脚是“无需插件”方案里唯一需要人工配合的系统级开关。我的习惯是在页面按钮旁边放一行灰色小字提示:请在弹出的打印窗口中选择“另存为 PDF”,并取消“页眉和页脚”。这行提示通过 .print-tip 类实现,屏幕上显示、打印时隐藏,不影响成品。</p> <pre><code class="language-css">.print-tip { color: #666; font-size: 12px; } @media print { .print-tip { display: none; } } </code></pre> <p>逻辑说明:.print-tip 在屏幕上给用户操作指引,进入打印流时隐藏。因为系统页眉页脚无法用 CSS 消除,唯一的办法是让用户手动取消勾选,提示文案是成本最低的兜底。如果你面对的导出场景是内部系统、操作者固定,可以把提示直接写进页面顶部,比每次弹对话框再解释效率高。</p> <p>参数说明:排版时上边距设 14~16mm 能避免用户忘记取消页眉时系统网址压住正文首行;确认用户一定会取消页眉后,可以缩回 10mm。不同浏览器对页眉页脚的默认开关不一致,Chrome 默认关背景图形,Edge 默认开背景图形,所以同一个页面在两个浏览器导出的效果会有视觉差异。让后台接收端不要只盯着一张截图渲验证,至少要跑两个主流浏览器各导一份。</p> <h3>4.3 多页内容与章节分页:break-before 控制每一章的起始页</h3> <p>长报告导出 PDF,最影响观感的是章节之间没有分页,上一章结尾和下一章开头挤在同一页。解决方式是给每个章节容器加 break-before: page,旧版本的 page-break-before: always 也一起写上,兼容老内核。这个规则对表格、标题、图片都生效,是排版层面的核心控制。</p> <p>另一个高频需求是“章节标题不要单独落在页尾”。一本书也好、一份报告也好,如果某页底部只有一行“3.2 供应链风险”,翻页才是正文,看起来非常业余。对应规则是给 h2、h3 加 break-inside: avoid,并给标题和后续内容建立连续关系。</p> <pre><code class="language-css">@media print { /* 新的一章从新页开始 */ .report-chapter { break-before: page; page-break-before: always; } /* 标题不要孤悬在页尾 */ .report-chapter > h2 { break-after: avoid; } h2, h3 { break-inside: avoid; } } </code></pre> <p>逻辑说明:break-before: page 让每个章节块强制从新页顶部开始,break-after: avoid 让标题和它后面的第一段正文尽量留在同一页。这样标题不会出现在一页的最底部,正文在下一页。这两个属性合起来,报告的分页观感会明显改善。</p> <p>参数说明:不要对每个表格都加分页,短表格前后会各留一整页空白,纸张浪费且观感差。分页规则和 @page margin 联动,边距改一次,所有断点位置都会重排,比如把上下边距从 14mm 改成 20mm,原本一页能装下的表格可能被推到第二页。改完边距,必须重新跑一遍完整打印预览检查断点。</p> <h2>5. 常见问题与排查:乱码、图片消失、表格截断的五个深坑</h2> <h3>5.1 打印对话框里找不到 PDF 打印机</h3> <p>现象:点击打印按钮后弹出系统打印对话框,但目标打印机列表里找不到“另存为 PDF”选项,只有物理打印机,或者连 PDF 输出都没有。</p> <p>原因:浏览器和操作系统版本差异。Windows 上打印到 PDF 由系统层的 PDF 打印机提供,如果系统组件缺失,浏览器对话框里就不会出现;macOS 的“存储为 PDF”藏在左下角的下拉菜单里;手机端浏览器则是先走“打印”,再选“保存为 PDF”,路径藏在子菜单里。用户在不同设备上操作,路径完全不一样,很容易觉得功能失效。</p> <p>解决:Windows 在系统设置的可选功能里启用系统 PDF 打印机;macOS 在打印对话框左下角下拉菜单里选“存储为 PDF”;手机端在打印选项里找“保存为 PDF”或“存储为 PDF”。交付方案时把这三条路径写进说明,比用户自己摸索省时间。这个问题不是代码问题,是运行环境的系统能力问题。</p> <h3>5.2 中文变成方块或问号,标题和正文字形不一致</h3> <p>现象:导出 PDF 里中文变成豆腐块状的空白方块,或者标题是一种字体、正文是另一种字体,风格明显割裂。</p> <p>原因:两种典型情况。第一种,页面用 @font-face 加载远程中文字体,打印时字体文件没有加载完,浏览器退回系统默认字体,但某些字形渲染不正常。第二种,项目用了 JS 绘图库把 DOM 画到 canvas 上,字体没有完整嵌入导出文件,PDF 阅读器打开了却没有对应字形文件。纯打印路线遇到这类问题,绝大多数是字体栈没写全。</p> <p>解决:打印样式里写完整的中文字体栈,并把远程字体的 font-display 设为 block,在 beforeprint 里用 document.fonts.ready 等字体就绪。排错顺序:先看屏幕显示是否正常,屏幕正常但 PDF 乱码,是打印时字体加载时机问题;屏幕就不正常,是字体栈或文件编码问题。这两个方向排查路径完全不同,别混着查。</p> <h3>5.3 图片在屏幕正常,打印出来却是空白或缩成一团</h3> <p>现象:页面上图片清晰可见,导出 PDF 后图片位置空白,或者只剩一个很小的占位框。</p> <p>原因:三种情况要分开排查。第一种,懒加载图片的 src 还是占位图,真实地址放在><link></div> </div> <div class="blog-tags"> <span>标签:</span> <a href="/jianzhan" class="tag">网站建设</a> <a href="/guanwang" class="tag">企业官网</a> <a href="/liucheng" class="tag">项目流程</a> <a href="/ui" class="tag">UI设计</a> <a href="/web" class="tag">前端开发</a> </div> <!-- <div class="blog-author"> <div class="author-avatar">作者</div> <div class="author-info"> <h4>张明</h4> <p> 创想科技高级项目经理,拥有8年网站建设经验,主导过100+企业官网项目。 </p> </div> </div> <div class="blog-navigation"> <a href="#" class="nav-btn nav-prev" >← 上一篇:响应式设计的最佳实践</a > <a href="#" class="nav-btn nav-next" >下一篇:网站性能优化的10个实用技巧 →</a > </div>--> </div> </div> </div> <div class="blog-sidebar"> <div class="sidebar-widget"> <h3>热门文章</h3> <ul class="popular-posts"> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5469367/">无人机视角多类别目标检测数据集:从标注格式到训练落地的完整链路</a> </h4> <div class="popular-post-date">2026/10/9 16:22:28</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5469362/">Zeek Broker 集群后端解析:固定对等连接策略、节点发现与集群布局配置</a> </h4> <div class="popular-post-date">2026/10/9 16:22:04</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5469269/">基于αβ坐标系的VSC实时功率控制器Simulink仿真与动态性能分析</a> </h4> <div class="popular-post-date">2026/10/9 16:18:43</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5469266/">智慧医疗HIS系统源码解析:从数据库设计到毕业设计答辩</a> </h4> <div class="popular-post-date">2026/10/9 16:18:25</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5469228/">ApexSQL Log与Recover:SQL Server误删/崩溃后数据恢复实战指南</a> </h4> <div class="popular-post-date">2026/10/9 16:16:09</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5469153/">Roo Code Tool 之 access_mcp_resource:MCP 资源访问能力与 TaoToken 统一通道实践</a> </h4> <div class="popular-post-date">2026/10/9 16:10:24</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5278687/">FFmpeg中AVPacket与AVFrame核心解析:内存、生命周期与音视频数据流</a> </h4> <div class="popular-post-date">2026/10/9 15:59:41</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5278694/">Java课设学生信息管理系统:JDBC+MySQL完整实现与避坑指南</a> </h4> <div class="popular-post-date">2026/10/8 13:15:55</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5278704/">空战对抗中的Q学习:从Q表到状态离散化与奖励塑形实战解析</a> </h4> <div class="popular-post-date">2026/10/9 15:59:29</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5278741/">JavaWeb仓库管理系统源码解析:部署、核心模块与二次开发</a> </h4> <div class="popular-post-date">2026/10/9 15:59:23</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5278750/">相衬成像原理与实操:让透明活细胞清晰可见</a> </h4> <div class="popular-post-date">2026/10/9 15:59:18</div> </div> </li> <li> <div class="popular-post-img">网站建设</div> <div class="popular-post-content"> <h4> <a href="/news/5278753/">基于HGE引擎的水浒传街机游戏源码分析与二次开发实战</a> </h4> <div class="popular-post-date">2026/10/9 15:59:11</div> </div> </li> </ul> </div> <div class="sidebar-widget"> <h3>文章分类</h3> <ul class="categories-list"> <li> <a href="/jianzhan">网站建设 <span>(12)</span></a> </li> <li> <a href="/sheji">设计思考 <span>(8)</span></a> </li> <li> <a href="/fenxiang">技术分享 <span>(15)</span></a> </li> <li> <a href="/anli">项目案例 <span>(6)</span></a> </li> <li> <a href="hangye">行业动态 <span>(5)</span></a> </li> </ul> </div> <div class="sidebar-widget"> <h3>标签云</h3> <div class="tag-cloud"> <a href="/tags/web">网站建设</a> <a href="/tags/xiangying">响应式设计</a> <a href="/tags/tiyan">用户体验</a> <a href="/tags/seo">SEO优化</a> <a href="/tags/web">前端开发</a> <a href="/tags/xiaochengxu">小程序</a> <a href="/tags/dianshang">电商平台</a> <a href="/tags/youhua">性能优化</a> </div> </div> </div> </div> </div> </section> <!-- 相关文章 --> <section class="related-posts"> <div class="container"> <div class="section-title"> <h2>相关文章</h2> <p>您可能感兴趣的其他内容</p> </div> <div class="related-grid"> <div class="related-card"> <div class="related-img">数据库课后答案的整理与验证:从doc到可信题库</div> <div class="related-content"> <div class="related-meta"> <span class="related-date">2026/10/9 15:30:51</span> <span class="related-category">网站建设</span> </div> <h3>数据库课后答案的整理与验证:从doc到可信题库</h3> <p> 简介&#xff1a;这是一份《数据库系统原理与设计》第四版教材的课后答案文档&#xff0c;面向正在学习数据库课程的高校学生、考研复习者以及需要快速核对课后习题的自学者。资源以单一doc文件形式整理&#xff0c;包体仅1个文件、约230KB&#xff0c;内容围绕数据库系统基础概…... </p> <a href="/news/5468529/" class="related-read-more" >阅读更多 →</a > </div> </div> <div class="related-card"> <div class="related-img">200个工程化登录模板:模块化结构与CSS变量驱动的前端实践</div> <div class="related-content"> <div class="related-meta"> <span class="related-date">2026/10/9 15:30:23</span> <span class="related-category">网站建设</span> </div> <h3>200个工程化登录模板:模块化结构与CSS变量驱动的前端实践</h3> <p> 简介&#xff1a;本资源是面向前端开发者与网页设计学习者的200套登录界面模板合集&#xff0c;聚焦HTML5语义化结构、CSS3动态样式&#xff08;含Flex/Grid布局、过渡动画&#xff09;、JavaScript表单验证与交互逻辑&#xff0c;以及jQuery简化DOM操作与AJAX无刷新提交等核心…... </p> <a href="/news/5468516/" class="related-read-more" >阅读更多 →</a > </div> </div> <div class="related-card"> <div class="related-img">AI Agent_13 模型里的「多少 B」是什么 详细讲解</div> <div class="related-content"> <div class="related-meta"> <span class="related-date">2026/10/9 15:29:11</span> <span class="related-category">网站建设</span> </div> <h3>AI Agent_13 模型里的「多少 B」是什么 详细讲解</h3> <p> 一句话先记住&#xff1a;B Billion&#xff0c;十亿。7B 70 亿参数&#xff0c;13B 130 亿参数&#xff0c;70B 700 亿参数。 这个数字指的是模型参数量&#xff08;Parameters&#xff09;&#xff0c;是大模型最常标注的规格。一、什么是参数&#xff08;Parameter&…... </p> <a href="/news/5468479/" class="related-read-more" >阅读更多 →</a > </div> </div> </div> </div> </section> <!-- CTA区域 --> <section class="cta"> <div class="container"> <h2>需要专业的网站建设服务?</h2> <p> 联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标 </p> <a href="/index.html#contact" class="btn">立即咨询</a> </div> </section> <!-- 页脚 --> <footer> <div class="container"> <div class="footer-content"> <div class="footer-column"> <h3>创想科技</h3> <p>专业网站建设与数字营销解决方案提供商,助力企业数字化转型。</p> </div> <div class="footer-column"> <h3>服务项目</h3> <ul> <li><a href="#">企业官网建设</a></li> <li><a href="#">电商平台开发</a></li> <li><a href="#">小程序开发</a></li> <li><a href="#">SEO优化</a></li> <li><a href="#">数字营销</a></li> </ul> </div> <div class="footer-column"> <h3>快速链接</h3> <ul> <li><a href="/index.html">首页</a></li> <li><a href="/index.html#portfolio">成功案例</a></li> <li><a href="blog.html">建站日记</a></li> <li><a href="/index.html#about">关于我们</a></li> <li><a href="/index.html#contact">联系我们</a></li> </ul> </div> <div class="footer-column"> <h3>联系我们</h3> <ul> <li>电话:400-123-4567</li> <li>邮箱:contact@chuangxiang.com</li> <li>地址:北京市朝阳区科技园区创新大厦A座10层</li> </ul> </div> </div> <div class="footer-bottom"> <p>© 2023 创想科技 版权所有 | 京ICP备12345678号</p> </div> </div> </footer> <script> // 移动端菜单切换 document .querySelector(".mobile-toggle") .addEventListener("click", function () { document.querySelector(".nav-menu").classList.toggle("active"); }); // 平滑滚动 document.querySelectorAll('a[href^="#"]').forEach((anchor) => { anchor.addEventListener("click", function (e) { e.preventDefault(); const targetId = this.getAttribute("href"); if (targetId === "#") return; const targetElement = document.querySelector(targetId); if (targetElement) { window.scrollTo({ top: targetElement.offsetTop - 80, behavior: "smooth", }); // 移动端点击后关闭菜单 if (window.innerWidth <= 768) { document.querySelector(".nav-menu").classList.remove("active"); } } }); }); </script> </body> </html>