riku
2025-08-13 bf42ef43fccdf3d3486eec84ad4073b0c7650aba
src/utils/doc.js
@@ -3,9 +3,110 @@
import docxtemplater from 'docxtemplater';
import ImageModule from 'docxtemplater-image-module-free';
import Pizzip from 'pizzip';
import PizZipUtils from 'pizzip/utils/dist/pizzip-utils';
import FileSaver from 'file-saver';
import fs from 'fs';
/**
 * 等比例缩放图片
 * 根据图片的长宽比进行不同方式的缩放
 * 如果宽度大于高度(横拍图片),则按照设定高度等比缩放;
 * 如果宽度小于高度(竖拍图片),则按照设定宽度等比缩放;
 * @param {Number} horizontalHeight 设定高度
 * @param {Number} verticalWidth 设定宽度
 * @param {*} img
 * @param {*} tagValue
 * @param {*} tagName
 * @returns
 */
function getSizeProportional(
  horizontalHeight,
  verticalWidth,
  img,
  tagValue,
  tagName
) {
  return new Promise(function (resolve, reject) {
    const image = new Image();
    image.src = tagValue;
    image.onload = function () {
      let width = image.width;
      let height = image.height;
      // console.log('width height', width, height);
      if (width > height && horizontalHeight && height > horizontalHeight) {
        const scale = image.height / horizontalHeight;
        height = horizontalHeight;
        width = image.width / scale;
      } else if (width <= height && verticalWidth && width > verticalWidth) {
        const scale = image.width / verticalWidth;
        width = verticalWidth;
        height = image.height / scale;
      }
      // console.log('scale', width, height);
      resolve([width, height]);
    };
    image.onerror = function (e) {
      console.log('img, tagValue, tagName : ', img, tagValue, tagName);
      alert('An error occured while loading ' + tagValue);
      reject(e);
    };
  });
}
/**
 * 固定大小缩放图片
 * 根据图片的长宽比进行不同方式的缩放
 * 如果宽度大于高度(横拍图片),则按照设定高度和宽高比缩放;
 * 如果宽度小于高度(竖拍图片),则按照设定宽度和宽高比缩放;
 * @param {*} horizontalHeight 设定高度
 * @param {*} verticalWidth 设定宽度
 * @param {*} scale 缩放比例,长边除短边的比例系数
 * @param {*} img
 * @param {*} tagValue
 * @param {*} tagName
 * @returns
 */
function getSizeFixed(
  horizontalHeight,
  verticalWidth,
  scale,
  img,
  tagValue,
  tagName
) {
  return new Promise(function (resolve, reject) {
    const image = new Image();
    image.src = tagValue;
    image.onload = function () {
      let width = image.width;
      let height = image.height;
      if (
        width > height &&
        horizontalHeight &&
        height > horizontalHeight &&
        scale
      ) {
        height = horizontalHeight;
        width = horizontalHeight * scale;
      } else if (
        width <= height &&
        verticalWidth &&
        width > verticalWidth &&
        scale
      ) {
        width = verticalWidth;
        height = verticalWidth * scale;
      }
      resolve([width, height]);
    };
    image.onerror = function (e) {
      console.log('img, tagValue, tagName : ', img, tagValue, tagName);
      alert('An error occured while loading ' + tagValue);
      reject(e);
    };
  });
}
/**
 * 获取图片配置信息
@@ -14,8 +115,8 @@
 * @returns
 */
function getImageOptions(options) {
  const horizontalHeight = options ? options.horizontalHeight : undefined
  const verticalWidth = options ? options.verticalWidth : undefined
  const horizontalHeight = options ? options.horizontalHeight : undefined;
  const verticalWidth = options ? options.verticalWidth : undefined;
  return {
    centered: false,
    fileType: 'docx',
@@ -30,34 +131,17 @@
        });
      });
    },
    getSize(img, tagValue, tagName) {
      return new Promise(function (resolve, reject) {
        const image = new Image();
        image.src = tagValue;
        image.onload = function () {
          let width = image.width;
          let height = image.height;
          // console.log('width height', width, height);
          if (width > height && horizontalHeight && height > horizontalHeight) {
            const scale = image.height / horizontalHeight;
            height = horizontalHeight;
            width = image.width / scale;
          } else if (width <= height && verticalWidth && width > verticalWidth) {
            const scale = image.width / verticalWidth;
            width = verticalWidth;
            height = image.height / scale;
          }
          // console.log('scale', width, height);
          resolve([width, height]);
        };
        image.onerror = function (e) {
          console.log('img, tagValue, tagName : ', img, tagValue, tagName);
          alert('An error occured while loading ' + tagValue);
          reject(e);
        };
      });
      // return getSizeProportional(horizontalHeight, verticalWidth, img, tagValue, tagName)
      return getSizeFixed(
        horizontalHeight,
        verticalWidth,
        options.scale,
        img,
        tagValue,
        tagName
      );
    }
  };
}
@@ -70,12 +154,15 @@
        throw error;
      }
      const zip = new Pizzip(content);
      const imageOptions = getImageOptions(imageSize);
      let doc = new docxtemplater()
        .setOptions({ paragraphLoop: true })
        .loadZip(zip)
        .attachModule(new ImageModule(imageOptions))
        .compile();
        .loadZip(zip);
      if (imageSize) {
        const imageOptions = getImageOptions(imageSize);
        doc.attachModule(new ImageModule(imageOptions));
      }
      doc.compile();
      doc.resolveData(data).then(() => {
        try {
          doc.render();