002 画个饼图

画个饼

要求:新增一个增删改查页面,每一条记录的数据,可以导出,也可以统计为饼图。

因为不熟悉前端,同时时间挺紧,这里采用的做法既见效也见笑。。。

维护菜单

我们不建表了,直接使用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}

完毕。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容