html转图片与pdf

189 阅读2分钟

html转图片与pdf

  • 需求:前端将局部或整体内容转为图片或pdf

图片

  • 使用到html2canvas库
  • 图片丢失问题:
    • canvas访问图片,某些不允许跨域,就会导致页面上空白,跨域信息会在控制台展示
    • 解决办法,使用本地图片或将存放图片的容器设置为可跨域访问
import html2canvas from "html2canvas";

const dom = document.querySelector("#downBox") as any;
const name = "离线文档.png";

html2canvas(dom, {
    allowTaint: true, // 允许污染
    useCORS: true,
    imageTimeout: 20000,
  })
    .then((canvas) => {
      let url = canvas.toDataURL("image/png");
      let a = document.createElement("a");
      let event = new MouseEvent("click");
      a.download = name;
      a.href = url;
      a.dispatchEvent(event);
      // 成功
    })
    .catch(() => {
      // 失败
    });

pdf

  • 核心api为window.print
  • 默认情况下是将整个页面转换为pdf,那么如果需要转换局部dom就需要做一些措施
    • 常见方案:
      • 转换前隐藏额外dom,转换后释放会有页面闪动,不推荐
      • 将需要转换的dom,插入iframe,然后调用iframe的print,完成后删除iframe用户无感下载,推荐
  • 背景图丢失:print转换的时候无法识别,使用img标签即可
 //拿到dom的结构和标签
  const printContentHtml = document.getElementById("downBox")?.outerHTML;
  // 创建iframe
  const iframe = document.createElement("iframe") as any;
  //设置iframe
  iframe.setAttribute(
    "style",
    "position:absolute;width:0px;height:0px;left:-500px;top:-500px;"
  );
  // 将所有的style拿到
  const styleInner = [...document.querySelectorAll("style")].reduce(
    (pre, ctx) => pre + ctx.innerHTML,
    ""
  );
  // 整合样式和dom,统一放入iframe
  const style = `<style>@media print {
    body{
       -webkit-print-color-adjust:exact;
       -moz-print-color-adjust:exact;
       -ms-print-color-adjust:exact;
       print-color-adjust:exact;
   } 
}${styleInner}</style>${printContentHtml}`;
  document.body.appendChild(iframe);
  iframe.contentDocument.write(style);
  // 在统一获取的dom中,有个别的小dom不需要展示,给它隐藏即可
  [...iframe.contentDocument.querySelectorAll(".printHidden")].forEach(
    (dom) => {
      dom.style.display = "none";
    }
  );
  iframe.contentDocument.close();
  iframe.contentWindow.print();
  document.body.removeChild(iframe);

最简单调用

@media print {
    body{
       -webkit-print-color-adjust:exact;
       -moz-print-color-adjust:exact;
       -ms-print-color-adjust:exact;
       print-color-adjust:exact;
   } 
   /* 隐藏a标签的href */
   a[href]:after {
          content: none !important;
        };
   xxx:{
      // 隐藏不想要的内容
      只会在打印时生效,不影响正常浏览
       display:none;
   }
}
window.print();