[vue-echarts-docxtemplater] Export word tables and pictures

Chapter 1 Vue Learning Practice

Foreword

According to the requirements, the page table and echarts chart need to be exported to a word document. Since I had not been involved in such requirements before, I went through many pitfalls and finally realized it. However, there are still many things that are unclear, and we will study them later when we have time.

1. Preparation

First use vue3 to lay out the page (the page is rather sloppy, and the data is simulated by mock), and then design the component that clicks to download. Save the page data on the desktop according to the template.

2. Usage steps

1. Import library

First import the required libraries: pizzip, docxtemplater, docxtemplater-image-module-free, jszip-utils, file-saver

import PizZip from "pizzip";
import docxtemplater from "docxtemplater";
import ImageModule from "docxtemplater-image-module-free";
import JSZipUtils from "jszip-utils";
import {<!-- --> saveAs } from "file-saver";

Download dependencies eg: yarn pizzip
yarn add docxtemplater-image-module-free: When yarn installation fails, the package.json file settings “dependencies”: {“docxtemplater-image-module-free”: “^1.1.1”, …} and then yran is Can.
If an error is reported and the declaration file of the module “file-saver” cannot be found, just declare it in the ***.d.ts file.

declare module "file-saver";
declare module "jszip-utils";
declare module "docxtemplater-image-module-free";

2. Part of the code

The code is as follows (example):

const props = defineProps<{<!-- -->
tableData: any[]; //Incoming table array
setItemRef: any[]; //Incoming base64 image list
[key: string]: any[]; //Other values that may be passed in
}>();

// Export echarts pictures, format conversion, official version, no modification required
const base64DataURLToArrayBuffer = (dataURL: string) => {<!-- -->
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;
};
// Click to export word
const exportWord = function () {<!-- -->
const imagelist = toRefs(props.setItemRef).map((val: any) => ({<!-- --> imgurl: val.value.imgurl }));
//Process the image path passed in by the parent component, [{imgurl: ''}, {imgurl: ''}]

// Read and obtain the binary content of the template file and put it in the project
//input.docx file. The vue2 document template needs to be placed in the static folder. The vue3 document template needs to be placed in the public folder. The document needs to have a .docx suffix. Renaming it directly from .doc will not work. It needs to be saved as .docx. Put the file name directly.
JSZipUtils.getBinaryContent("input.docx", function (error: any, content: any) {<!-- -->
if (error) {<!-- -->
throw error;
}

//Image processing
let opts = {<!-- -->};
opts = {<!-- -->
centered: true, //whether the image is centered, true: the image is centered in word
getImage: (chartId: any) => {<!-- -->
return base64DataURLToArrayBuffer(chartId);
},
//Customize the specified image size. Here you can dynamically debug the size of each image.
getSize: (img: any, tagValue: any, tagName: any) => {<!-- -->
if (tagName === "imgurl") return [700, 350]; //Set the image width and height, tagName: passed in variable
return [600, 350];
}
};
//Create a PizZip instance with the content of the template
let zip = new PizZip(content);
//Create and load docxtemplater instance object
let doc = new docxtemplate();
doc.attachModule(new ImageModule(opts));
doc.loadZip(zip);
//Set the value of the template variable
doc.setData({<!-- -->
table: props.tableData, //word document variables
imagels: imagelist
});
try {<!-- -->
// Replace all template variables with their values
doc.render();
} catch (error: any) {<!-- -->
\t\t\t// throw an exception
let e = {<!-- -->
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties
};
console.log(JSON.stringify({<!-- --> error: e }));
throw error;
}
// Generate a zip file representing the docxtemplater object (not a real file, but an in-memory representation)
let out = doc.getZip().generate({<!-- -->
type: "blob",
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
//Save the target file object as a file of the target type and name it
saveAs(out, "demo.docx");
});
};

3.Error

1)Cant find end of central directory:is this a zip file?
Possible reason 1: The file name is incorrect.
Place the file according to the above method, and the template address in the code cannot include slashes.
Possible reason 2: The template file suffix is incorrect.
Save as .docx template file.
2) End of data reached (data length = 0, asked index = 4). Corrupted zip?
The template file is an empty file.
3) Uncaught Error: TemplateError: Multi error at XMLHttpRequest.xhr.onreadystatechange
The word template table should start with {#table} and end with {/table}
4) The image output is blank, and there is an error message (I forgot the specific error message)
Check whether the image information exported by echarts is blank.

//Check
<img ref="imgurl" alt="" />
let imgurl = ref();
imgurl.value.src = chartV.value.getDataURL({<!-- -->});
//chartV is the ref of the echarts chart
//If the picture is blank, the animation of the option attribute of the first echarts chart: false (the method I found online, mine still does not appear)
//The second method is to use a timer to get the image address (my picture appears)
onMounted(() => {<!-- -->
setTimeout(() => {<!-- -->
imgurl.value = chartV.value.getDataURL({<!-- -->
type: "png",
pixelRatio: 1,
backgroundColor: "#fff"
});
}, 0);
});
//Export the image address at this time and save it
defineExpose({<!-- --> //Last export
imgurl
});

Results display

docx document

3. Summary

Tips: The specific code is in the folder of middleground/tabEcharts
The above are all the records of converting Vue charts and tables into word. If there are any changes, please revise them as soon as possible.

references:

Fang Moumou.(2020).vue exports echarts charts and text to word.CSDN blog. Taken from https://blog.csdn.net/laiAhaha/article/details/111267297