用浏览器把 HTML 详情页导出成长图 / PDF 工具(附核心思路)

📅 2026/8/11 11:15:18
用浏览器把 HTML 详情页导出成长图 / PDF 工具(附核心思路)
用浏览器把 HTML 详情页导出成长图 / PDF附核心思路写商品详情、图文教程时经常会遇到这种情况内容是HTML写的预览很舒服店铺、小程序、网盘说明却只要长图或PDF截屏拼接费劲打印另存又容易跑版其实在浏览器里就能做把 HTML 渲染出来 → 调好宽度 → 截成一张长图或再塞进 PDF。下面只讲实现思路和关键代码方便自己改、自己集成。1. 整体流程载入 HTML 片段 ↓ 放进固定宽度的预览容器如 750 / 1200 ↓ 等图片加载完成 ↓ DOM → Canvas截图 ↓ Canvas → PNG 下载 或 Canvas → jsPDF → PDF 下载宽度建议先定死再截场景常用宽度手机详情长图750部分电商稿790电脑宽图1200预览用多少宽导出就按这个宽截比「先截再缩放」稳得多。2. 预览容器先所见再所得dividstagestylewidth:750px;background:#fff;margin:0 auto;!-- 这里塞你的 HTML 详情片段 --/div如果原文根节点写了max-width:750px在导出容器里可以强制撑满#stage .export-root{max-width:none!important;width:100%!important;margin-left:0!important;margin-right:0!important;box-sizing:border-box;}宽度切换只改容器不要改用户 HTML 里每一处样式functionsetPreviewWidth(px){document.getElementById(stage).style.widthpxpx;}3. 导出前先等图片外链图没加载完就截容易出现空白块asyncfunctionwaitForImages(root){constimgs[...root.querySelectorAll(img)];awaitPromise.all(imgs.map((img){if(img.completeimg.naturalWidth)return;returnnewPromise((resolve){img.addEventListener(load,resolve,{once:true});img.addEventListener(error,resolve,{once:true});});}));}外链图若站点不允许跨域Canvas 会「污染」或缺图。实务上常见处理图床开启 CORS或导出前改成本地可访问路径或用能把资源嵌进结果的截图库仍依赖对方是否放行4. DOM 转长图两种常见做法方案 Ahtml2canvas兼容广asyncfunctionexportPng(stage,scale2){awaitwaitForImages(stage);constcanvasawaithtml2canvas(stage,{scale,// 2 高清但个别排版可能和预览略有差异useCORS:true,backgroundColor:#ffffff,width:stage.offsetWidth,height:stage.scrollHeight,});canvas.toBlob((blob){constadocument.createElement(a);a.hrefURL.createObjectURL(blob);a.downloadexport.png;a.click();});}注意scale 1时库会按放大后的逻辑重算文字行内带背景的代码块最容易和浏览器预览对不齐。不对齐时优先试scale: 1。方案 B基于 SVG foreignObject 的截图更贴预览很多「精确模式」工具会走类似modern-screenshot/html-to-image这条路先克隆 DOM再画进 Canvas文字换行通常更接近真实页面。// 示意具体 API 以你引入的库为准constcanvasawaitmodernScreenshot.domToCanvas(stage,{scale:2,backgroundColor:#ffffff,});工程上可以默认精确模式失败再回退 html2canvas。5. 长图再转 PDF有了 Canvas 之后用jsPDF很直接asyncfunctionexportPdf(canvas,modelong){const{jsPDF}window.jspdf;constimgcanvas.toDataURL(image/jpeg,0.92);constpxToMm0.264583;// 按 96dpi 近似if(modelong){// 单页长 PDF页面尺寸跟图走constwcanvas.width*pxToMm;consthcanvas.height*pxToMm;constpdfnewjsPDF({orientation:wh?l:p,unit:mm,format:[w,h],});pdf.addImage(img,JPEG,0,0,w,h);pdf.save(export.pdf);return;}// A4 分页一张长图切多页constpdfnewjsPDF({orientation:p,unit:mm,format:a4});constpageWpdf.internal.pageSize.getWidth();constpageHpdf.internal.pageSize.getHeight();constimgWpageW;constimgH(canvas.height*imgW)/canvas.width;letheightLeftimgH;letposition0;pdf.addImage(img,JPEG,0,position,imgW,imgH);heightLeft-pageH;while(heightLeft0.5){position-pageH;pdf.addPage();pdf.addImage(img,JPEG,0,position,imgW,imgH);heightLeft-pageH;}pdf.save(export.pdf);}浏览器对 Canvas 高度有上限常见大约一万多像素量级。内容特别长时需要降清晰度、拆段截取或换服务端渲染Puppeteer 一类这是前端方案的硬边界。6. 减少「预览正常、导出错位」实操里最有用的几条预览宽度 导出逻辑宽度例如直接用 750而不是 375 再 ×2 指望布局一样出问题先把清晰度改成1x行内code/ 带背景的span可加code, kbd, samp{box-decoration-break:clone;-webkit-box-decoration-break:clone;}短路径文字必要时display: inline-block; white-space: nowrap;避免截图引擎把灰底拆成两截。7. 最小可运行骨架拼起来!DOCTYPEhtmlhtmllangzh-CNheadmetacharsetUTF-8/titleHTML → 长图 Demo/titlescriptsrchttps://cdn.jsdelivr.net/npm/html2canvas1.4.1/dist/html2canvas.min.js/script/headbodybuttonidbtn导出 PNG/buttondividstagestylewidth:750px;margin:20px auto;background:#fff;padding:16px;h1示例标题/h1p把你的详情 HTML 贴到这里。/p/divscriptdocument.getElementById(btn).onclickasync(){conststagedocument.getElementById(stage);constcanvasawaithtml2canvas(stage,{scale:2,useCORS:true,backgroundColor:#ffffff,});constadocument.createElement(a);a.downloaddemo.png;a.hrefcanvas.toDataURL(image/png);a.click();};/script/body/html本地保存成.html用 Chrome / Edge 打开即可试。正式使用再补宽度预设、PDF、精确截图引擎、跨域与错位处理。8. 小结核心不是「神奇算法」而是固定宽度预览 DOM 截图 可选写入 PDF难度主要在图片跨域、超长画布、高清缩放导致的文字错位自己写个 Demo 很快要做成每天能用的成品还得把预览、预设、导出选项和避坑打磨一遍如果你只是想直接用现成的本地小工具调宽度预览、导出 PNG/PDF可以在这边看看整理好的版本https://zhixuanxingqiu.com浏览器打开即用按需自取本文只讲原理方便学习与二次改造。