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、点击生成报告结果如下

相关推荐
人工智能培训2 分钟前
大语言模型:从语言理解到通用智能的跃迁
linux·服务器·前端·人工智能
一拳不是超人13 分钟前
做独立开发三个月,我的第一个产品终于有了 1000 个用户
前端·程序员
Amos_Web23 分钟前
Rspack 源码解析(十):Hash 与 Asset 生成
前端·rust·源码阅读
福兮说25 分钟前
用 IndexedDB 存用户的文件,我踩过的五个坑
前端·javascript
闪耀之光M7825 分钟前
前端依赖自动导入:unplugin-auto-import
前端
Ricon组态薄荷糖40 分钟前
Ricon组态系统:工业组件开发指南与实践
前端·后端·物联网
flash俊杰1 小时前
Electron 桌面应用的进程模型:为什么 fork Next.js standalone
前端
沙蒿同学1 小时前
我把架构约定编译成了会变红的测试:Wails v2 + Go + Vue3 桌面脚手架实战
前端·后端·github
cpolar技术支持1 小时前
本地 Playwright 测试报告怎么远程复盘?Trace Viewer 跑起来后,用 cpolar 分享失败现场
前端·自动化测试·测试工具·cpolar·playwright
wordbaby1 小时前
企业级后台管理系统路由设计与最佳实践指南
前端