docxtemplater避坑!!! 前端导出word怎么插入当地图片或base64 有完备示例 ...

打印 上一主题 下一主题

主题 527|帖子 527|积分 1581

用docxtemplater库实现前端通过模板导出word,遇到需求,要插图片并转成word并导出,在图片转换这块遇到了题目,网上查示例大多都跑不通,本身琢磨半天,总算搞明确了。
附上清楚完备示例,供参考。
如有不懂,私我询问!

首先需要一个word文件作为模板


必须是docx文件!!!

{%} 代表图片 xgq是变量
安装需要的包

  1. npm install docxtemplater
  2. npm install docxtemplater-image-module-free
  3. npm install pizzip
  4. npm install file-saver
  5. npm install html2canvas # 如需截图的话 安装
复制代码
  1. import Docxtemplater from 'docxtemplater';
  2. import { saveAs } from 'file-saver';
  3. import PizZip from 'pizzip';
  4. import ImageModule from 'docxtemplater-image-module-free';
  5. import html2canvas from 'html2canvas';
  6. import image from './20240522152640.jpg';
  7. import docx from './test.docx';
复制代码
插入当地图片并转换

  1. const imageData = await fetch(image);
  2. const imageArrayBuffer = await imageData.arrayBuffer();
  3. const imgDataDict: Record<string, ArrayBuffer> = {
  4.   xgq: imageArrayBuffer,
  5. };
  6. const docxData = await fetch(docx);
  7. const docxArrayBuffer = await docxData.arrayBuffer();
  8. const zip = new PizZip(docxArrayBuffer);
  9. const doc = new Docxtemplater(zip, {
  10.   paragraphLoop: true,
  11.   linebreaks: true,
  12.   modules: [
  13.     new ImageModule({
  14.       getImage: (value: string, key: string) => {
  15.         return imgDataDict[key];
  16.       },
  17.       getSize: (afterValue: ArrayBuffer, value: string, key: string) => {
  18.         return [400, 400];
  19.       },
  20.     }),
  21.   ],
  22. });
  23. doc.render({
  24.   xgq: "xgq", // 这里得是字符串否则会报错
  25. });
  26. const blob = doc.getZip().generate({
  27.   type: "blob",
  28.   mimeType:
  29.     "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  30. });
  31. saveAs(blob, "download.docx");
复制代码
插入base64图片并转换

  1. const base64 =
  2.   "data:image/jpeg;base64,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";
  3. const imageArrayBuffer = base64DataURLToArrayBuffer(base64);
  4. const imgDataDict: Record<string, ArrayBuffer> = {
  5.   xgq: imageArrayBuffer,
  6. };
  7. const docxData = await fetch(docx);
  8. const docxArrayBuffer = await docxData.arrayBuffer();
  9. const zip = new PizZip(docxArrayBuffer);
  10. const doc = new Docxtemplater(zip, {
  11.   paragraphLoop: true,
  12.   linebreaks: true,
  13.   modules: [
  14.     new ImageModule({
  15.       getImage: (value: string, key: string) => {
  16.         return imgDataDict[key];
  17.       },
  18.       getSize: (afterValue: ArrayBuffer, value: string, key: string) => {
  19.         return [400, 400];
  20.       },
  21.     }),
  22.   ],
  23. });
  24. doc.render({
  25.   xgq: "xgq", // 这里得是字符串否则会报错
  26. });
  27. const blob = doc.getZip().generate({
  28.   type: "blob",
  29.   mimeType:
  30.     "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  31. });
  32. saveAs(blob, "download.docx");
复制代码
  1. const base64DataURLToArrayBuffer = (dataURL: string) => {
  2.   const base64Regex = /^data:image\/(png|jpg|jpeg|svg|svg\+xml);base64,/;
  3.   if (!base64Regex.test(dataURL)) {
  4.     return false;
  5.   }
  6.   const stringBase64 = dataURL.replace(base64Regex, "");
  7.   let binaryString;
  8.   if (typeof window !== "undefined") {
  9.     binaryString = window.atob(stringBase64);
  10.   } else {
  11.     binaryString = new Buffer(stringBase64, "base64").toString("binary");
  12.   }
  13.   const len = binaryString.length;
  14.   const bytes = new Uint8Array(len);
  15.   for (let i = 0; i < len; i++) {
  16.     const ascii = binaryString.charCodeAt(i);
  17.     bytes[i] = ascii;
  18.   }
  19.   return bytes.buffer;
  20. };
复制代码
截图某个网页地区并插入转换

  1. <div id="test" style={{ border: "1px solid red", width: 300 }}>
  2.   <div>截图</div>
  3.   <button type="button">666</button>
  4.   <br />
  5.   <img src={image} />
  6. </div>;
复制代码
  1. const dom: any = document.getElementById("test");
  2. const canvas = await html2canvas(dom, {
  3.   useCORS: true,
  4.   scale: 5,
  5. });
  6. const imageDataURL = canvas.toDataURL("image/png");
  7. const response = await fetch(imageDataURL);
  8. const imageArrayBuffer = await response.arrayBuffer();
  9. const imgDataDict: Record<string, ArrayBuffer> = {
  10.   xgq: imageArrayBuffer,
  11. };
  12. const docxData = await fetch(docx);
  13. const docxArrayBuffer = await docxData.arrayBuffer();
  14. const zip = new PizZip(docxArrayBuffer);
  15. const doc = new Docxtemplater(zip, {
  16.   paragraphLoop: true,
  17.   linebreaks: true,
  18.   modules: [
  19.     new ImageModule({
  20.       getImage: (value: string, key: string) => {
  21.         return imgDataDict[key];
  22.       },
  23.       getSize: (afterValue: ArrayBuffer, value: string, key: string) => {
  24.         return [400, 400];
  25.       },
  26.     }),
  27.   ],
  28. });
  29. doc.render({
  30.   xgq: "xgq", // 这里得是字符串否则会报错
  31. });
  32. const blob = doc.getZip().generate({
  33.   type: "blob",
  34.   mimeType:
  35.     "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  36. });
  37. saveAs(blob, "download.docx");
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

老婆出轨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表