画个饼
要求:新增一个增删改查页面,每一条记录的数据,可以导出,也可以统计为饼图。
因为不熟悉前端,同时时间挺紧,这里采用的做法既见效也见笑。。。
维护菜单
我们不建表了,直接使用menu
数据。进入系统,维护一个菜单。
新增页面
把menu
页面复制过来,改为views/report/list/index.vue
将按钮改为导出word
以及展示饼图
,其中饼图借用了crud.toEdit
方法:
<el-table-column v-if="checkPer(['admin','menu:edit','menu:del'])" label="操作" width="260px" align="center" fixed="right">
<template slot-scope="scope">
<el-button size="small" type="primary" @click="exportWord(scope.row)">导出word</el-button>
<el-button size="mini" type="success" @click="crud.toEdit(scope.row)">查看饼图</el-button>
</template>
</el-table-column>
定义饼图
修改components/Echarts/PieChart.vue
自己做一个MyPieChart.vue
//props中增加:
chartData: {
type: Object,
required: true
}
//methods.initchart改为:
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.setOptions(this.chartData)
},
// methods新增setOptions方法,将menu的几个数字特性,作为饼图百分比
setOptions(form) {
console.log(form)
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: '10',
data: ['subCount', 'type', 'menuSort', 'cache', 'hidden']
},
calculable: true,
series: [
{
name: 'Menu Pie',
type: 'pie',
roseType: 'radius',
radius: [15, 95],
center: ['50%', '40%'],
data: [
{ value: form.subCount, name: 'subCount' },
{ value: form.type, name: 'type' },
{ value: form.menuSort, name: 'menuSort' },
{ value: form.cache, name: 'cache' },
{ value: form.hidden, name: 'hidden' }
],
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
})
引入饼图
在index.vue
中:
//引用饼图
import PieChart from '@/components/Echarts/MyPieChart'
//修改dialog页面,展示饼图,数据源为form
<el-dialog append-to-body :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="580px">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<div class="dashboard-container">
<div class="dashboard-editor-container">
<el-row :gutter="32">
<!-- <el-col :xs="24" :sm="24" :lg="8"> -->
<el-col :xs="24" :sm="24" :lg="24">
<div class="chart-wrapper">
<pie-chart :chart-data="form" />
</div>
</el-col>
</el-row>
</div></div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
</div>
</el-dialog>
如无意外,饼图展示已完成。
导出word
index.vue
中新增methods.exportWord
,如下:
//引入方法
import JSZipUtils from 'jszip-utils'
import Docxtemplater from 'docxtemplater'
import Pizzip from 'pizzip'
import { saveAs } from 'file-saver'
// 导出word
exportWord(row) {
const _this = this
const tableData = _this.$data.crud.data
const bodyData = { name: row.id, tel: '13309388888', need: '物美价廉', remark: '已通过质检', total: '9999', checkNote: '批准' }
// ['name', 'tel', 'need', 'remark', 'total', 'checkNote']
console.log(_this.$data.crud.data)
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent('/input.docx', function(error, content) {
// input.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
// 抛出异常
if (error) {
throw error
}
// 创建一个JSZip实例,内容为模板的内容
const zip = new Pizzip(content)
// 创建并加载docxtemplater实例对象
const doc = new Docxtemplater().loadZip(zip)
// 设置模板变量的值
doc.setData({
...bodyData,
table: tableData
})
try {
// 用模板变量的值替换所有模板变量
doc.render()
} catch (error) {
// 抛出异常
const e = {
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties
}
console.log(JSON.stringify({ error: e }))
throw error
}
// 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
const out = doc.getZip().generate({
type: 'blob',
mimeType:
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
})
// 将目标文件对象保存为目标类型的文件,并命名
const outName = '报表明细' + bodyData.name + '.docx'
saveAs(out, outName)
})
}
由于使用了一些插件,记得
npm install docxtemplater pizzip
npm install jszip --save
npm install jszip-utils --save
npm install file-saver --save
记得在/public
目录下放个input.docx
作为模板,内容如下:
header:
xxxx{name} xxxx{tel}
xxxx{need}
xxxx{remark}
明细内容
{#table}
{id}
{label}
{menuSort}
{subCount}
{subCount}
{createTime}
{/table}
footer:{checkNote}
完毕。