egg(九):下载excel文件,前后端

前言:

       egg实现后端提供下载接口,前端直接a标签调用,也可以直接用浏览器访问地址下载。

实现效果:

页面输入  http://localhost:7001/toexecl ,下载下文件,名称,样式可调整

后端:

1、安装插件 exceljs ,(附:  exceljs中文api )

cnpm install exceljs --save

2、引入:

const ExcelJS = require('exceljs');

ES5 导入

const ExcelJS = require('exceljs/dist/es5');

3、app/service  新建文件 common.js  这里配置excel的具体配置

const Service = require('egg').Service;
const Excel = require('exceljs');

class CommonService extends Service {
  /**
   * 数据并生成excel
   * @param {Array} headers excel标题栏
   * @param {Array} param 数据参数
   * @param {string} name 文件名称
   */
   async excelCommon(headers, data, name) {
      let columns = [];// exceljs要求的columns
      let hjRow = {};// 合计行
      let titleRows = headers.length;// 标题栏行数

      // 处理表头
      headers.forEach(row=>{
        row.forEach(col=>{
          let { f, t ,w} = col;
          if (f){
            if (col.totalRow) hjRow[f] = true;
            if (col.totalRowText) hjRow[f] = col.totalRowText;
            col.style = { alignment: { vertical: 'middle', horizontal: 'center' } };
            col.header = t; //文字
            col.key = f; //对应的字段
            col.width = w ? w : 15;//宽度
            columns.push(col);
          }
        })
      })

      let workbook = new Excel.Workbook();
      let sheet = workbook.addWorksheet('My Sheet', { views: [{ xSplit: 1, ySplit: 1 }] });
      sheet.columns = columns;
      sheet.addRows(data);

      // 处理复杂表头
      if (titleRows > 1) {
        // 头部插入空行
        for (let i = 1; i < titleRows; i++)  sheet.spliceRows(1, 0, []);

        headers.forEach(row=>{
          row.forEach(col=>{
            if (col.m1){
              sheet.getCell(col.m1).value = col.t;
              sheet.mergeCells(col.m1 + ":" + col.m2);
            }

          })
        })

      }

      // 处理样式、日期、字典项
      sheet.eachRow(function (row, rowNumber) {
        // 设置行高
        row.height = 25;
        row.eachCell({ includeEmpty: true },  (cell)=> {
          // 设置边框 黑色 细实线
          const top = { style: 'thin', color: { argb: '000000' } };
          const left = { style: 'thin', color: { argb: '000000' } };
          const bottom = { style: 'thin', color: { argb: '000000' } };
          const right = { style: 'thin', color: { argb: '000000' } };
          cell.border = { top, left, bottom, right };

          // 设置标题部分为粗体
          if (rowNumber <= titleRows) { cell.font = { bold: true }; return; }
        });
      });
      this.ctx.set('Content-Type', 'application/vnd.openxmlformats');
      // 这个地方的空格不要更改
      this.ctx.set('Content-Disposition', "attachment;filename*=UTF-8' '" + encodeURIComponent(name) + '.xlsx');
      this.ctx.body = await workbook.xlsx.writeBuffer();
    }
}
module.exports = CommonService;

4、配置路由

module.exports = app => {
    const { router, controller } = app;

    app.get('/toexecl', controller.new.downExcel.toexecl);

}

5、具体操作部分:controller/new/downExcel.js

const Controller = require('egg').Controller;
class downFileController extends Controller {
    async toexecl() {
        const { ctx } = this;
        //两层数组,一层是行,一层是列,允许多行
        let headers = [
            [
                { t: '下单时间', f: 'trade_time', totalRow: true },
                { t: '订单类型', f: 'order_type', totalRow: true },
                { t: '手机号码', f: 'phone_number', totalRow: true },
                { t: '扫描状态', f: 'scan_status', totalRow: true },
                { t: '交易状态', f: 'ctf_order_status', totalRow: true },
                { t: '订单份额(克)', f: 'trade_share', totalRow: true },
                { t: '当时账号总份额(克)', f: 'account_share', totalRow: true ,w:25},
                { t: '订单号', f: 'order_no', totalRow: true },
            ]
        ];
        let data = [
            { trade_time: '2020-12-10', order_type:'线上', phone_number:'18374009921', scan_status:'1', ctf_order_status:'1', trade_share:'2', account_share:'2', order_no:'164656456546' },
            { trade_time: '2020-12-10', order_type:'线下', phone_number:'18374009921', scan_status:'1', ctf_order_status:'1', trade_share:'2', account_share:'2', order_no:'164656456546' }
        ] // 需要在这边自己适配数据,这边为空

        await ctx.service.common.excelCommon(headers, data, '订单信息');
    }
}
module.exports = downFileController;

6、如果有具体需要,可以将data的数据,从其他方法里面,调用mysql来获取到,下面:

egg(七):实现列表的模糊查询_Ponnenult的博客-CSDN博客前言: 列表数据系列增删改查的查询实现实现步骤:1、路由配置:/** * 路由配置 * @param app */module.exports = app => { const { router, controller } = app; //-------------------------------------------------- //用户信息 app.get('/getUserList', controller.new....https://blog.csdn.net/weixin_44727080/article/details/120656448

7、查看页面:

输入:http://localhost:7001/toexecl

可以看到下载成功了!

前端部分:

1.第一种方法:downFile(下载地址, 保存名称);

function downFile(content, filename) {
    // 创建隐藏的可下载链接
    var eleLink = document.createElement('a');
    eleLink.download = filename;
    eleLink.style.display = 'none';
    // 字符内容转变成blob地址
    var blob = new Blob([content]);
    eleLink.href = URL.createObjectURL(blob);
    // 触发点击
    document.body.appendChild(eleLink);
    eleLink.click();
    // 然后移除
    document.body.removeChild(eleLink);
};

2.第二种方法:

<a href="/api/getImg" download="file.xlsx">下载</a>

其他相关资料:

egg 生成Excel - 简书

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值