前端导出word插入图片及表格

<template>
  <div>
    <button @click="generateWordDocument">生成Word文档</button>
    <div id="main" style="width: 600px; height: 400px"></div>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import {
  Document,
  Packer,
  Paragraph,
  ImageRun,
  Table,
  TableRow,
  TableCell,
  AlignmentType,
  WidthType,
  TextRun
} from "docx";
import * as echarts from "echarts";
import { saveAs } from "file-saver";
const chart = ref(null);
// 示例ECharts配置
const chartConfig = {
  title: {
    text: "示例图表",
  },
  tooltip: {},
  legend: {
    data: ["销量"],
  },
  xAxis: {
    data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"],
  },
  yAxis: {},
  series: [
    {
      name: "销量",
      type: "bar",
      data: [5, 20, 36, 10, 10, 20],
    },
  ],
};

const dataURLtoBlob = (dataURL) => {
  const arr = dataURL.split(",");
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
};

const initExhart = () => {
  chart.value = echarts.init(document.getElementById("main"));
  chart.value.setOption(chartConfig);
};
onMounted(() => {
  initExhart();
});
const generateWordDocument = () => {
  const chartDataURL = chart.value.getDataURL({
    type: "png",
    pixelRatio: 2,
    excludeComponents: ["toolbox"],
  });
  const chartImageBlob = dataURLtoBlob(chartDataURL);
  // 示例表格数据
  const tableData = [
    { column1: "数据1", column2: "数据2" },
    { column1: "数据3", column2: "数据4" },
    { column1: "数据5", column2: "数据6" },
    { column1: "数据5", column2: "数据6" },
    { column1: "数据5", column2: "数据6" },
    { column1: "数据5", column2: "数据6" },
    { column1: "数据5", column2: "数据6" },
    { column1: "数据5", column2: "数据6" },
    { column1: "数据5", column2: "数据6" },
  ];

  // 创建表格行
  const tableRows = tableData.map((row) => {
    return new TableRow({
      children: [
        new TableCell({
          children: [new Paragraph(row.column1)],
        }),
        new TableCell({
          children: [new Paragraph(row.column2)],
        }),
        new TableCell({
          children: [new Paragraph(row.column1)],
        }),
        new TableCell({
          children: [new Paragraph(row.column2)],
        }),
        new TableCell({
          children: [new Paragraph(row.column1)],
        }),
        new TableCell({
          children: [new Paragraph(row.column2)],
        }),
        new TableCell({
          children: [new Paragraph(row.column1)],
        }),
        new TableCell({
          children: [new Paragraph(row.column2)],
        }),
      ],
    });
  });

  // 添加表头
  const headerRow = new TableRow({
    children: [
      new TableCell({
        children: [new Paragraph("分行")],
        shading: {
          fill: "D9D9D9",
        },
      }),
      new TableCell({
        children: [new Paragraph("业务量")],
        shading: {
          fill: "D9D9D9",
        },
      }),
      new TableCell({
        columnSpan: 3,
        children: [new Paragraph("用印总用时")],
        shading: {
          fill: "D9D9D9",
        },
      }),

      new TableCell({
        columnSpan: 3,
        children: [new Paragraph("用印有效用时")],
        shading: {
          fill: "D9D9D9",
        },
      }),
    ],
  });

  const headerRowTwo = new TableRow({
    children: [
      new TableCell({
        children: [new Paragraph("")],
        shading: {
          fill: "D9D9D9",
        },
      }),
      new TableCell({
        children: [new Paragraph("")],
        shading: {
          fill: "D9D9D9",
        },
      }),
      //用印总用时
      new TableCell({
        children: [new Paragraph("2024年一季度")],
        shading: {
          fill: "D9D9D9",
        },
      }),
      new TableCell({
        children: [new Paragraph("较上季度")],
        shading: {
          fill: "D9D9D9",
        },
      }),
      new TableCell({
        children: [new Paragraph("较去年一季度")],
        shading: {
          fill: "D9D9D9",
        },
      }),
      //有效用时
      new TableCell({
        children: [new Paragraph("2024年一季度")],
        shading: {
          fill: "D9D9D9",
        },
      }),
      new TableCell({
        children: [new Paragraph("较上季度")],
        shading: {
          fill: "D9D9D9",
        },
      }),
      new TableCell({
        children: [new Paragraph("较去年一季度")],
        shading: {
          fill: "D9D9D9",
        },
      }),
    ],
  });

  const styles = {
    paragraphStyles: [
      {
        id: "Normal",
        name: "Normal",
        run: {
          font: "Arial",
        },
      },
      {
        id: "Heading1",
        name: "Heading 1",
        basedOn: "Normal",
        next: "Normal",
        quickFormat: true,
        run: {
          size: 45,
          bold: true,
        },
        paragraph: {
          alignment: AlignmentType.CENTER,
          spacing: {
            before: 240,
            after: 120,
          },
        },
      },
    ],
  };
  // 创建Word文档
  const doc = new Document({
    styles: styles,
    sections: [
      {
        properties: {},
        children: [
          //   new Paragraph({
          //     text: "电子用印时效分析图",
          //     heading: 1,
          //   }),
          new Paragraph({
            children: [
              new TextRun({
                text: "电子用印时效分析图",
                bold: true,
                size: 24,
              }),
            ],
            alignment: AlignmentType.left,
            spacing: {
              before: 240,
              after: 120,
            },
          }),
          new Paragraph({
            children: [
              new ImageRun({
                data: chartImageBlob,
                transformation: {
                  width: 450,
                  height: 337,
                },
              }),
            ],
          }),
          new Paragraph({
            children: [
              new TextRun({
                text: "2024年一季度电子用印时效分析表",
                bold: true,
                size: 24,
              }),
            ],
            alignment: AlignmentType.left,
            spacing: {
              before: 240,
              after: 120,
            },
          }),
          //添加表格
          new Table({
            rows: [headerRow, headerRowTwo, ...tableRows],
            width: {
              size: 100,
              type: WidthType.PERCENTAGE,
            },
          }),

          //分析描述
          new Paragraph({
            children: [
              new TextRun({
                text: "分析结论",
                bold: true,
                size: 24,
              }),
            ],
            alignment: AlignmentType.left,
            spacing: {
              before: 240,
              after: 120,
            },
          }),
          //分析描述-con
          new Paragraph({
            children: [
              new TextRun({
                text: " this is a test text",
                bold: false,
                size: 18,
              }),
            ],
            alignment: AlignmentType.left,
            spacing: {
              before: 240,
              after: 120,
            },
          }),
        ],
      },
    ],
  });
  Packer.toBlob(doc).then((buffer) => {
    saveAs(buffer, "output.docx");
    console.log("文档已生成");
  });
};
</script>

<style scoped></style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值