首页 > 其他分享 >前端实现导出word文档docx格式

前端实现导出word文档docx格式

时间:2023-06-05 17:48:03浏览次数:41  
标签:src docx word image base64 return 文档 let docxtemplater

说明

前端实现导出word文档,我们需要用到docxtemplater这个库
使用的是vue2.6和vue-cli5
还需要准备一个word模板,更多模板变量请去docxtemplater官网获取

准备

word模板
image

安装需要用到的库

// 安装 docxtemplater
npm install docxtemplater pizzip  --save

// 安装 jszip-utils
npm install jszip-utils --save

// 安装 FileSaver
npm install file-saver --save

// 安装 angular-expressions
npm install angular-expressions --save

// 图片模块,没有图片需求可以不装
npm install docxtemplater-image-module-free

代码

<template>
    <div>
        <button @click="generateDocx">Generate Docx</button>
    </div>
</template>
<script>
// 如果有图片渲染的需求,要调用getBase64Sync 方法
import { exportWord, getBase64Sync } from './index.js'
export default {
    data() {
        return {
            content: {
                title: "fdf辅导费",
                name:'小新',
                age:5,
                imageOpts: "./logo.png",
                custName:'custName',
                phoneNumber:'458888883',
                projectRequirement:'projectRequirement',
                remark:'备注哦哦哦哦',
                checkReason:'审核checkReason',
                company:'abc公司',
                table:[
                    {id:1,name:'空调',number:15,salePrice:50,saleTotal:30,remark:'肯德基肯德基',src:require('../../assets/list/进行中.png')},
                    {id:2,name:'冰箱',number:15,salePrice:50,saleTotal:30,remark:'经济金融',src:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png'},
                    {id:3,name:'电风扇',number:15,salePrice:50,saleTotal:30,remark:'会更好',src:'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png'},
                    {id:4,name:'彩电',number:15,salePrice:50,saleTotal:30,remark:'韩国进口',src:'./logo.png'},
                ]
            }
        };
    },
    methods: {
        async generateDocx() {
	//把图片转成base64
            this.content.imageOpts = await getBase64Sync(this.content.imageOpts)
            for (let i = 0; i < this.content.table.length; i++) {
                this.content.table[i].src = await getBase64Sync(this.content.table[i].src);
            }
            console.log(this.content);
	//这里的模版放到pubilc目录下
            exportWord('./test.docx', this.content, '测试.docx',{src:[50,50]})
        }
    }
};
</script>

调用的index.js文件

import PizZip from 'pizzip'
import docxtemplater from 'docxtemplater'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'
// import ImageModule from 'docxtemplater-image-module-free';
// import expressions from 'angular-expressions';

/**
 * 把连接或者本地图片转成base64
 * @param {string} imgUrl 
 * @returns 
 */
export function getBase64Sync(imgUrl) {
    return new Promise(function (resolve, reject) {
        // 一定要设置为let,不然图片不显示
        let image = new Image();
        // 解决跨域问题
        image.crossOrigin = "anonymous";
        //图片地址
        image.src = imgUrl;
        // image.onload为异步加载
        image.onload = function () {
            let canvas = document.createElement("canvas");
            canvas.width = image.width;
            canvas.height = image.height;
            let context = canvas.getContext("2d");
            context.drawImage(image, 0, 0, image.width, image.height);
            //图片后缀名
            let ext = image.src
                .substring(image.src.lastIndexOf(".") + 1)
                .toLowerCase();
            //图片质量
            let quality = 0.8;
            //转成base64
            let dataurl = canvas.toDataURL("image/" + ext, quality);
            //返回
            resolve(dataurl);
        };
    });
}
/**
 * 将base64格式的数据转为ArrayBuffer
 * @param {Object} dataURL base64格式的数据
 */
function base64DataURLToArrayBuffer(dataURL) {
    const base64Regex = /^data:image\/(png|jpg|jpeg|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 = Buffer.from(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;
}

/**
 * 导出word,支持图片
 * @param {Object} tempDocxPath 模板文件路径
 * @param {Object} wordData 导出数据
 * @param {Object} fileName 导出文件名
 * @param {Object} imgSize 自定义图片尺寸,{src:[50,50]}
 */
export const exportWord = (tempDocxPath, wordData, fileName, imgSize) => {
    // 这里要引入处理图片的插件
    var ImageModule = require('docxtemplater-image-module-free');

    const expressions = require("angular-expressions");

    // 读取并获得模板文件的二进制内容
    JSZipUtils.getBinaryContent(tempDocxPath, function (error, content) {
        // console.log('tempDocxPath', tempDocxPath);
        if (error) {
            throw error;
        }

        expressions.filters.size = function (input, width, height) {
            return {
                data: input,
                size: [width, height],
            };
        };

        // function angularParser (tag) {
        //   const expr = expressions.compile(tag.replace(/’/g, "'"));
        //   return {
        //     get (scope) {
        //       return expr(scope);
        //     },
        //   };
        // }

        // 图片处理
        let opts = {}

        opts = {
            // 图像是否居中
            centered: false
        };

        opts.getImage = (chartId) => {
            // console.log(chartId);//base64数据
            // 将base64的数据转为ArrayBuffer
            return base64DataURLToArrayBuffer(chartId);
        }

        opts.getSize = function (img, tagValue, tagName) {
            // console.log(img);//ArrayBuffer数据
            // console.log(tagValue);//base64数据
            // console.log(tagName);//wordData对象的图像属性名
            // 自定义指定图像大小
            if (imgSize.hasOwnProperty(tagName)) {
                return imgSize[tagName];
            } else {
                return [150, 150];
            }
        }

        // 创建一个PizZip实例,内容为模板的内容
        let zip = new PizZip(content);
        // 创建并加载docxtemplater实例对象
        let doc = new docxtemplater();
        doc.attachModule(new ImageModule(opts));
        doc.loadZip(zip);

        doc.setData(wordData);

        try {
            // 用模板变量的值替换所有模板变量
            doc.render()
            
        } catch (error) {
    // 抛出异常
    let e = {
        message: error.message,
        name: error.name,
        stack: error.stack,
        properties: error.properties
    };
    console.log(JSON.stringify({
        error: e
    }));
    throw error;
}

// 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
let out = doc.getZip().generate({
    type: "blob",
    mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
// 将目标文件对象保存为目标类型的文件,并命名
saveAs(out, fileName);
    });
}

标签:src,docx,word,image,base64,return,文档,let,docxtemplater
From: https://www.cnblogs.com/tn666/p/17458519.html

相关文章

  • 如何将word图片粘贴到KindEditor里面
    ​ 这种方法是servlet,编写好在web.xml里配置servlet-class和servlet-mapping即可使用后台(服务端)java服务代码:(上传至ROOT/lqxcPics文件夹下)<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><%@     page contentType="text/html;cha......
  • 如何将word图片粘贴到wangEditor里面
    ​ 如何做到ueditor批量上传word图片?1、前端引用代码<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML1.0Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>......
  • git环境安装文档
    Git环境搭建(一)原创 小胡子 小胡子笔记 2023-05-2321:20 发表于广东收录于合集#git2个一、搭建gitLab环境1、简介Git是分布式版本控制系统,分为两种类型的仓库:本地仓和远程仓库。本地仓库:开发人员自己电脑上的Git仓库远程仓库:远程服务器上的Git仓库基本指令:clon......
  • 2023最新IntellJ IDEA诺依SpringCloud开发部署文档(保姆级别)
    目录若依RuoYiv3.6.2部署文档一、环境构建二、模块描述三、部署后端1、下载到本地。2、MySQL导入数据。3、Nacos修改(1)保证本地Nacos下载安装成功,修改本地Nacos的application.properties。(2)启动本地的Nacos.4、启动本地的Redis5、启动如下模块四、部署前端1、保证Node安装没有......
  • vscode插件开发----获得当前打开文档对应的工作区根目录
    代码如下:exportfunctionactivate(context:any){//注册一个命令letdisposable=vscode.commands.registerCommand('codeStat.countCurFile',function(){leteditor=vscode.window.activeTextEditor;if(editor){constcurrentDoc......
  • Java High Level Rest Client---查询文档
    查询文档的基本步骤1)准备Request对象2)准备请求参数3)发起请求4)解析响应示例解析以match_all查询为例代码解读:第一步,创建SearchRequest对象,指定索引库名第二步,利用request.source()构建DSL,DSL中可以包含查询、分页、排序、高亮等query():代表查询条件,利用QueryBuilder......
  • 调整word序号的格式
     点击定义新编号格式是设置左顶格或右顶格。 右键字体设置大小......
  • 云原生之使用Docker部署TeaKKi知识文档管理工具
    (云原生之使用Docker部署TeaKKi知识文档管理工具)一、TeaKKi介绍Teakki是一款知识文档管理工具,当前支持企业本地私有化部署,免费试用有效期30天。适用于团队,企业的知识协作和管理.,为你构建团队的知识库!TeaKKi专注知识知识协作,让团队知识协作变得简单高效。二、检查docker......
  • Easy Music 说明文档
    1.顶部搜索栏:   功能描述:进行歌曲搜索状态描述:点击时展开搜索栏,输入歌手名/歌曲名时,进行列表筛选。2.菜单栏:功能描述:打开菜单状态描述:点击时从左边弹出菜单栏。 3.下......
  • Word复制过去源格式也不对问题
    我在做毕业论文的时候,各种材料文档要集成在一个文档。结果复制过去,不是表格断了就是字间距宽了,OpenType选项变灰等字体问题,等等。这其实是word文档的兼容模式,老文档字间距紧凑,而新文档间距拉长。结果可能造成表格断开到第二页。如果要转换成最新的版本,方法是:菜单栏的“文件”(“......