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

相关推荐
华仔啊8 小时前
10分钟搞定!SpringBoot+Vue3 整合 SSE 实现实时消息推送
java·vue.js·后端
Mike_jia8 小时前
DBSyncer:开源数据同步中间件全景实战指南
前端
y***86698 小时前
JavaScript在Node.js中的Electron
javascript·electron·node.js
烛阴8 小时前
从`new`关键字开始:精通C#类与对象
前端·c#
天若有情6739 小时前
笑喷!乌鸦哥版demo函数掀桌怒怼主函数:难办?那就别办了!
java·前端·servlet
记得记得就1519 小时前
【Nginx 实战系列(一)—— Web 核心概念、HTTP/HTTPS协议 与 Nginx 安装】
前端·nginx·http
天蓝色的鱼鱼9 小时前
mescroll老用户亲测z-paging:这些功能让我果断切换!
前端·uni-app
JarvanMo9 小时前
适用于 iOS 开发者的 Flutter 3.38:Xcode 与 Swift 集成新技巧
前端
北极糊的狐9 小时前
Vue 中 vue-awesome-swiper的使用笔记(适配 Vue2/Vue3)
前端·javascript·vue.js
anyup9 小时前
🔥100+ 天,已全面支持鸿蒙!uView Pro 近期更新盘点及未来计划
前端·uni-app·harmonyos