前后端生成Excel下载的差异

前言

最近在做一个的一个项目(Yii2.0 + vue 2.5)有一个Excel导出的需求,分别用前后端的方法来生成,这里对比一下两者的差异

后端生成

一开始我是不知道前端也可以把数据直接生成Excel下载的,所以第一个想法就是直接用PHP的插件来完成这个事情,以前用过phpExcel,上GitHub搜索的时候发现,作者15年就开始不再维护这个项目了,而是转而去做另外一个叫PhpSpreadsheet的项目,其实也是可以做Excel的各种操作,composer下来

这里需要注意fileinfo的扩展才能正确安装上

第一种,直接保存文件在服务器

然后写了这么一个类,大概使用方法就是在head里面指定了字段,会从data里面找到合适的字段分别写到Excel里面去,然后保存在服务器里面,再返回给前端一个连接,前端就只需要window.open(line)就OK了,很简单

<?php

namespace common\libs;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

/**
 * excel类
 */
class Excel
{
    public function save($data, $head, $name = '')
    {
        if (empty($data)) {
            return false;
        }

        $spreadsheet = new Spreadsheet();
        try {
            $sheet = $spreadsheet->getActiveSheet();
            $j     = 65;
            foreach ($head as $item) {
                $str = chr($j) . '1';
                $sheet->setCellValue($str, $item);
                $j++;
            }
            $i = 2;
            foreach ($data as $v) {
                $j = 65;
                // 这里主要是拿头的的key,用于匹配上合适的字段
                foreach ($head as $k => $item) {
                    // 从A开始
                    $str = chr($j) . $i;
                    $sheet->setCellValue($str, $v[$k]);
                    $j++;
                }

                $i++;

            }

            $writer = new Xlsx($spreadsheet);
            $dir    = 'assets/excel';
            is_dir($dir) OR mkdir($dir, 0777, true);
            $fileName = $dir . '/' . time() . rand(000001, 999999) . '.xlsx';
            $writer->save($fileName);

            return $fileName;
        } catch (\Exception $e) {
            \Yii::error($e);
            return false;
        }

    }
}

第二种,生成文件流(也需要前端配合)

这种方式,首先后端的生成Excel基本上是没有改变的, 然后最后保存的那也改一下

$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');

$writer->save('php://output');
exit;

这里返回到前端的会是这样一个形式

所以我们在前端请求的方法里面就需要注意告诉这是一个bolb对象

axios({
    // 用axios发送post请求
    method: 'get',
    url: 'access/load-search-list', // 请求地址
    params: data, // 参数
    responseType: 'blob', // 表明返回服务器返回的数据类型
    headers: {
        'Content-Type': 'application/json'
    }
}).then(res => {
    this.loading = false

    const content = res.data
    const blob = new Blob([content])
    const fileName = '导出信息.xlsx'
    if ('download' in document.createElement('a')) {
        // 非IE下载
        const elink = document.createElement('a')
        elink.download = fileName
        elink.style.display = 'none'
        elink.href = URL.createObjectURL(blob)
        document.body.appendChild(elink)
        elink.click()
        URL.revokeObjectURL(elink.href) // 释放URL 对象
        document.body.removeChild(elink)
    } else {
        // IE10+下载
        navigator.msSaveBlob(blob, fileName)
    }

})

前端直接生成

因为我项目用的是d2admin,发现是可以直接在前端生成Excel直接下载的,看了一下代码,十分简单

引入插件

yarn add @d2-projects/vue-table-export

main.js 使用

import pluginExport from '@d2-projects/vue-table-export'


Vue.use(pluginExport)

代码使用

首先定义好表头,label是你需要在表头里面显示的字段,然后data里面必须含有prop的字段,然后就可以了,很简单

const columns = [
{
    prop: 'id',
    label: 'id'
},
{
    prop: 'url',
    label: '落地页'
},
{
    prop: 'word',
    label: '搜索词'
},
{
    prop: 'ip',
    label: 'ip'
},
{
    prop: 'area',
    label: '地区'
},
{
    prop: 'addTime',
    label: '时间'
}
]
this.$export
.excel({
    columns,
    data: data
})
.then(() => {
    this.$message('导出表格成功')
})

差异

后端生成更稳定

一般我们做Excel导出的时候,会数据量有可能比较大,数据量如果太大,传输到前端的时候,会对浏览器的性能有一定要求,但是如果是后端生成,只需要给前端一个链接用于下载就可以了

前端生成不占用空间

后端生成需要在服务器生成一个文件,而前端则不用,直接就可以在浏览器生成Excel了

后端可以做文件缓存

一般我们导出一个Excel,这个Excel可能是有固定性的,譬如上个月的某个数据,这个数据是固定的,也就是说,我只要生成一遍以后,以后无论是谁,需要是要这个Excel,我可以直接给链接,而不用到数据库里面去查询,而前端则不行,你每次都需要查询数据库(当然你也可以把数据缓存下来,但是这样就失去了前端生成的意义了,缓存的文件也会很大)

总结

最后我还是选用了前端直接生成的方法,其实这个是和我项目有关系的,我的项目里面每次需要的数据不算很大,而且我还有查询的语句,我后端不需要做很大的修改就可以了,如果在后端生成(无论是文件还是文件流),我后端代码和前端代码都需要做很大的修改

转载于:https://my.oschina.net/gcdong/blog/3009425

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前后导出Excel文件有两种实现方式。 第一种是在前直接将页面上的DOM元素打印到Excel文件。这种方式适用于所有数据在当前页面展示的情况。可以使用Vue自带的方法,将页面上的DOM元素转换成Excel表格,并保存为Excel文件。具体实现代码如下: ``` export function exportDomToXlsx(dom, name) { const table_book = XLSX.utils.table_to_book(dom, { raw: true }) const table_write = XLSX.write(table_book, { bookType: 'xlsx', bookSST: true, type: 'array' }) try { FileSaver.saveAs( new Blob([table_write], { type: 'application/octet-stream' }), name + '.xlsx' ) } catch (e) { console.log(e, table_write) } } ``` 这个方法会将指定的DOM元素转换成Excel文件,并以给定的文件名保存。 第二种方式是在某些场景下,比如要导出的数据列表是分页的,或者需要导出的数据需要从后获取的情况下,需要通过调用后接口来实现导出。这种方式需要前后分离,前调用后接口来获取导出的数据并生成Excel文件。 综上所述,前后导出Excel文件的实现方式有两种,根据具体场景选择合适的方式来实现导出功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [前后分离场景下导出excel方法如何产品化?](https://blog.csdn.net/qq_42887496/article/details/123117949)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值