vue纯前端根据页面或者后台数据,读取本地文档模板,填充数据后并导出

最近接了个活,需要根据表格数据和用户给定的文档模板,生成报告,因为没得后端,所以做了一个纯前端的生成报告并下载,现实如下:

纯前端根据页面或者后台数据,读取本地文档模板,填充数据后并导出

1、技术 vue3 + element-plus 或者 vue2 + element-ui

2、安装依赖

javascript 复制代码
npm install docxtemplater
npm install pizzip
npm install file-saver

3、模板文件,以doc为例,放在本地public

4、具体代码实现(复制可用)

javascript 复制代码
<!-- 前端实现,获取本地文档模板,在页面上根据数据,导出一个有数据的word -->
<template>
  <el-table :data="tableData" style="width: 100%">
    <el-table-column label="Date" width="180">
      <template #default="scope">
        <div style="display: flex; align-items: center">
          <el-icon><timer /></el-icon>
          <span style="margin-left: 10px">{{ scope.row.date }}</span>
        </div>
      </template>
    </el-table-column>
    <el-table-column label="Name" width="180">
      <template #default="scope">
        <el-popover effect="light" trigger="hover" placement="top" width="auto">
          <template #default>
            <div>name: {{ scope.row.name }}</div>
            <div>address: {{ scope.row.address }}</div>
          </template>
          <template #reference>
            <el-tag>{{ scope.row.name }}</el-tag>
          </template>
        </el-popover>
      </template>
    </el-table-column>
    <el-table-column label="Operations">
      <template #default="scope">
        <el-button size="small" @click="generateReport(scope.row)">生成报告</el-button>
        <el-button size="small" @click="handleEdit(scope.$index, scope.row)">Edit</el-button>
        <el-button  size="small"  type="danger"  @click="handleDelete(scope.$index, scope.row)">Delete</el-button>
      </template>
    </el-table-column>
  </el-table>
</template>

<script setup>
// import Docxtemplater from 'docxtemplater'
// import PizZip from 'pizzip'
import { saveAs } from 'file-saver'



const tableData = [
  {
    date: '2016-05-03',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-02',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-04',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-01',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
]
const handleEdit = (index,row ) => {
  console.log(index, row)
}
const handleDelete = (index, row) => {
  console.log(index, row)
}


const generateReport = async (row) => {console.log(row)
  try {
    // 1. 加载Word模板文件
    console.log(window.origin)
    const response = await fetch('/mb.docx')
    const arrayBuffer = await response.arrayBuffer()
    
    // 2. 初始化docxtemplater(老版本)
    // const zip = new PizZip(arrayBuffer)
    // const doc = new Docxtemplater().loadZip(zip)
    
    //新
    const PizZip = require('pizzip');
    const Docxtemplater = require('docxtemplater');
    const zip = new PizZip(arrayBuffer);
    const doc = new Docxtemplater(zip);

    // 3. 准备模板数据(根据你的Word模板结构调整)
    let templateData = {
      title: '数据分析报告',
      name:row.name,
      date:row.date,
      address:row.address,
    }
    
    // 4. 渲染模板
    doc.render(templateData)
    
    // 5. 生成并下载文件
    const out = doc.getZip().generate({ type: 'blob' })
    saveAs(out, `数据分析报告_${new Date().getTime()}.docx`)
  } catch (error) {
    console.error('生成报告失败:', error)
  }
}
</script>

5、点击生成报告结果如下

相关推荐
slim~12 分钟前
javaweb基础第一天总结(HTML-CSS)
前端·css·html
一支鱼16 分钟前
leetcode常用解题方案总结
前端·算法·leetcode
小浣熊喜欢揍臭臭26 分钟前
react+umi项目如何添加electron的功能
javascript·electron·react
惜.己29 分钟前
针对nvm不能导致npm和node生效的解决办法
前端·npm·node.js
乖女子@@@42 分钟前
React笔记_组件之间进行数据传递
javascript·笔记·react.js
F2E_Zhangmo1 小时前
基于cornerstone3D的dicom影像浏览器 第二章 加载本地文件夹中的dicom文件并归档
前端·javascript·css
念念不忘 必有回响1 小时前
js设计模式-装饰器模式
javascript·设计模式·装饰器模式
用户21411832636021 小时前
Nano Banana免费方案来了!Docker 一键部署 + 魔搭即开即用,小白也能玩转 AI 图像编辑
前端
weixin_584121431 小时前
vue3+ts导出PDF
javascript·vue.js·pdf
Zacks_xdc2 小时前
【前端】使用Vercel部署前端项目,api转发到后端服务器
运维·服务器·前端·安全·react.js