将后端数据转换为docx文件

使用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);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值