使用docx
npm install docx
按照注释处理数据并转换为对应的bolb数据流
<template>
<Button type="primary" @click="handleDocxCreate">{{
buttonTitle || "报告生成"
}}</Button>
</template>
<script>
import {
Document,
Paragraph,
TextRun,
Packer,
AlignmentType,
Table,
TableCell,
TableRow,
WidthType,
BorderStyle,
} from "docx";
export default {
props: {
buttonTitle: {
// 报告生成
type: String,
},
docxData: {
type: Array,
required: true,
// [
// {
// isTable: Boolean, // 是否为表格,默认为false,若table为true,则data必填,其余忽略
// isAlignment: String, // 字段位置,默认为LEFT,可以为BOTH,CENTER,END,LEFT,RIGHT,START...
// isIndent: Boolean, // 是否首行缩进两个字符,默认为false
// text: String, // 内容
// size: Number, // 字体大小,默认为22
// font: String, // 字体类型,默认为仿宋
// isBold: Boolean, // 是否加粗,默认为false
// data: [ // Array
// [
// {
// text: String, // 表格单元格内容
// width: Number, // 单元格宽度,默认为每个单元格平均分配宽度,如果不设置则会自动计算
// columnSpan: Number, // 合并单元格,默认为1
// isBolb: Boolean, // 是否加粗,默认为false
// size: Number, // 字体大小,默认为22
// font: String, // 字体类型,默认为仿宋
// }
// ]
// ], // 表格数据,如果isTable为true,则必填
//
// }
// ]
},
},
data() {
return {
};
},
methods: {
/**
* 文件blob流生成
*/
async handleDocxCreate() {
// 创建 Word 文档
const doc = new Document({
sections: [
{
properties: {},
children: this.docxData.map((item) => {
// 如果是表格,则处理表格数据
if (item.isTable) {
return this.handleTabel(item.data);
} else {
// 否则处理普通文本段落
return new Paragraph({
alignment: AlignmentType[item.isAlignment || "LEFT"],
indent: {
firstLine: item.isIndent ? 500 : 0, // 直接设置缩进值(单位为twips,1厘米=567twips,约1.27厘米缩进)
},
children: [
new TextRun({
text: item.text || '',
bold: item.isBold || false,
size: item.size || 22,
font: item.font || "仿宋",
}),
],
});
}
}),
},
],
});
// 生成 Blob 对象
const blob = await Packer.toBlob(doc);
},
/**
* 表格
* @param {*} data
*/
handleTabel(data) {
const table = new Table({
width: {
size: 100,
type: WidthType.PERCENTAGE,
},
rows: data.map(
(row, rowIndex) =>
new TableRow({
children: row.map((cell, cellIndex) => {
// 合并单元格
return new TableCell({
width: {
size: cell.width || (cell.length / row.length) * 100,
type: WidthType.PERCENTAGE,
},
columnSpan: cell.columnSpan || 1,
children: [
new Paragraph({
alignment: AlignmentType.CENTER,
children: [
new TextRun({
text: cell.text || '',
bold: cell.isBolb || false,
size: cell.size || 22,
font: cell.font || "仿宋",
}),
],
}),
],
// 可选:设置单元格样式
shading: { fill: "F3F3F3" }, // 背景色
borders: {
top: {
style: BorderStyle.SINGLE,
size: 4,
color: "000000",
},
bottom: {
style: BorderStyle.SINGLE,
size: 4,
color: "000000",
},
left: {
style: BorderStyle.SINGLE,
size: 4,
color: "000000",
},
right: {
style: BorderStyle.SINGLE,
size: 4,
color: "000000",
},
},
});
}),
})
),
// 设置表格对齐为左对齐
alignment: AlignmentType.LEFT,
borders: {
top: { style: BorderStyle.SINGLE, size: 4, color: "000000" },
bottom: { style: BorderStyle.SINGLE, size: 4, color: "000000" },
left: { style: BorderStyle.SINGLE, size: 4, color: "000000" },
right: { style: BorderStyle.SINGLE, size: 4, color: "000000" },
},
});
return table;
},
},
};
</script>
<style scoped>
</style>
若需要将该文件传给后端,需要转换bolb数据流的类型
let formData = new FormData();
// 转换文件类型
const file = new File([blob], `${this.fileName || "报告.docx"}`, {
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
formData.append("file", file);
ajax
.post(uploadUrl, formData)
.then((response) => {
console.log("文件上传成功", response);
})
文件下载
const downloadLink = document.createElement("a");
const blobUrl = URL.createObjectURL(blobData);
downloadLink.href = blobUrl;
downloadLink.download = "name.docx";
downloadLink.click();
URL.revokeObjectURL(blobUrl);

437

被折叠的 条评论
为什么被折叠?



