Docxtemplater 实现前端在线生成word,并添加签名图片到指定位置,图片去四周无用透明区域

Docxtemplater 实现前端在线生成word,并添加签名图片到指定位置,图片去四周无用透明区域

import Docxtemplater from "docxtemplater";
import PizZip from "pizzip";
import JSZipUtils from "jszip-utils";
import ImageModule from "docxtemplater-image-module-free";

function fileToBase64(file, resolve) {
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = function(e) {
    // e.target.result 即为base64结果
    clearblankimg(e.target.result, resolve);
  };
}

//签名图片处理
function clearblankimg(imgData, resolve) {
  var img = new Image(); //创建图片对象
  img.src = imgData;
  img.onload = function() {
    var c = document.createElement("canvas"); //创建处理画布对象
    var ctx = c.getContext("2d");
    c.width = img.width;
    c.height = img.height;
    ctx.drawImage(img, 0, 0); //绘制
    var imgData = ctx.getImageData(0, 0, c.width, c.height).data; //读取图片数据
    var lOffset = c.width,
      rOffset = 0,
      tOffset = c.height,
      bOffset = 0;
    for (var i = 0; i < c.width; i++) {
      for (var j = 0; j < c.height; j++) {
        var pos = (i + c.width * j) * 4;
        if (
          imgData[pos] == 255 ||
          imgData[pos + 1] == 255 ||
          imgData[pos + 2] == 255 ||
          imgData[pos + 3] == 255
        ) {
          bOffset = Math.max(j, bOffset); // 找到有色彩的最下端
          rOffset = Math.max(i, rOffset); // 找到有色彩的最右端
          tOffset = Math.min(j, tOffset); // 找到有色彩的最上端
          lOffset = Math.min(i, lOffset); // 找到有色彩的最左端
        }
      }
    }
    lOffset++;
    rOffset++;
    tOffset++;
    bOffset++;
    var x = document.createElement("canvas"); //创建处理后画布对象
    x.width = rOffset - lOffset;
    x.height = bOffset - tOffset;
    var xx = x.getContext("2d");
    xx.drawImage(
      img,
      lOffset,
      tOffset,
      x.width,
      x.height,
      0,
      0,
      x.width,
      x.height
    ); //绘制
    resolve(x.toDataURL());
    console.log(x.toDataURL()); //得到最终裁剪出来的base64
  };
}

function base64DataURLToArrayBuffer(dataURL) {
  const base64Regex = /^data:image\/(png|jpg|svg|svg\+xml);base64,/;
  if (!base64Regex.test(dataURL)) {
    return false;
  }
  const stringBase64 = dataURL.replace(base64Regex, "");
  let binaryString;
  if (typeof window !== "undefined") {
    binaryString = window.atob(stringBase64);
  } else {
    binaryString = new Buffer(stringBase64, "base64").toString("binary");
  }
  const len = binaryString.length;
  const bytes = new Uint8Array(len);
  for (let i = 0; i < len; i++) {
    const ascii = binaryString.charCodeAt(i);
    bytes[i] = ascii;
  }
  return bytes.buffer;
}

const editer = {
  exportWordAndImage(reportData, url, resolve3) {
    JSZipUtils.getBinaryContent(url, (error, content) => {
      if (error) {
        console.error(error);
        return;
      }

      const promise = new Promise((resolve, reject) => {
        fileToBase64(reportData.signImg, resolve);
      });
      promise.then(base64N => {
        let signImg = base64N;

        // 图片处理
        let opts = {};
        // opts.centered = true; // 图片居中,在word模板中定义方式为{%src} 
        opts.fileType = "docx";
        opts.getImage = function(chartId) {
          return base64DataURLToArrayBuffer(chartId);
        };
        opts.getSize = function() {
          return [100, 50];
        };
        const imageModule = new ImageModule(opts);

        const zip = new PizZip(content);
        const doc = new Docxtemplater()
          .loadZip(zip)
          .setOptions({ paragraphLoop: true, linebreaks: true }) // 换行确认,如果你有的文本中有换行符的话,可以选择它导入到word起不起作用
          .attachModule(imageModule)
          .compile();

        doc
          .resolveData({
            // 这是你导入的数据,这个数据体中的属性或对象一定要和word模板中的插值一样
            ...reportData,
            signImg
          })
          .then(() => {
            console.log("Export...");
            doc.render();
            const out = doc.getZip().generate({
              type: "blob",
              mimeType:
                "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
            });

            let file = new window.File(
              [out],
              "购销协议.docx",
              { type: "docx" }
            );
            //弹出下载
            // saveAs(out, "购销协议.docx");
            // console.log(file);
            resolve3(file); // 直接返回生成file
            // 输出文档,可以自定义自己的文档名
            //
          });
      });
    });
  }
};

export default editer;

方法调用

const promise = new Promise((resolve, reject) => {
        editer.exportWordAndImage(data, "static/file/tem/ukey.docx", resolve);
      });
      promise.then(res => {
        this.file3 = res;
        // console.log(res);
      });

在这里插入图片描述

模板

传入的对象对应的key,设置好就可以在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以为您提供一些思路和建议,但是具体实现可能需要涉及编程技巧和相关工具的使用。 1. 文本文件处理 首先,您需要将指定的文本文件读入程序,并进行一些必要的处理。您可以使用Python中的文件操作函数来读取文件内容,例如: ```python with open('text.txt', 'r') as f: content = f.read() ``` 接着,您需要对文本内容进行一些处理,例如去除无用字符、分词、统计词频等。这里我们可以使用Python中的第三方库,例如jieba和collections。具体的处理方法可以参考相关文档和示例代码。 2. 图片文件处理 在生成词云时,您可以选择将词云的形状设置为指定图片。这需要对图片进行一些处理,使其能够被词云生成器所使用。您可以使用Python中的第三方库,例如Pillow和numpy,来进行图片处理。 具体来说,您需要将图片转换为numpy数组,再进行一些处理,例如将颜色转换为灰度、二值化、去除噪声等。然后,您可以将处理后的图片数组传递给词云生成器,作为词云的形状。 3. 词云生成 最后,您需要使用词云生成生成词云,并保存为图片文件。您可以选择使用Python中的第三方库,例如wordcloud和matplotlib来生成词云。 具体来说,您需要将处理后的文本内容和图片形状传递给词云生成器,设置一些参数,例如词云形状、字体、颜色等,然后调用生成函数,生成词云并保存为图片文件。示例代码如下: ```python from wordcloud import WordCloud import matplotlib.pyplot as plt import numpy as np from PIL import Image # 读取文本文件 with open('text.txt', 'r') as f: content = f.read() # 读取图片文件并处理 img = Image.open('image.png') img_array = np.array(img.convert('L')) processed_img = some_processing_function(img_array) # 生成词云 wc = WordCloud(background_color='white', mask=processed_img, font_path='font.ttf') wc.generate(content) # 显示词云并保存为图片文件 plt.imshow(wc, interpolation='bilinear') plt.axis('off') plt.show() wc.to_file('wordcloud.png') ``` 以上是一个简单的实现思路,您可以根据自己的需求和技能进行调整和优化。希望对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值