Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

datatables 需要把表格数据导出成一个excel表格文件,包含多个worksheet #356

Closed
brucemj opened this issue May 30, 2018 · 4 comments
Labels
Essence 精华 √Solved 已解决

Comments

@brucemj
Copy link

brucemj commented May 30, 2018

使用 datatables 把数据展示成表格已经OK。
使用 excel buttons 也实现了把表格导出成 excel 文件。
但是默认导出的 excel 只有一个 sheet

现在需要把表格数据导出成一个excel表格文件,包含多个sheet,如何实现?

@occultskyrong
Copy link
Collaborator

occultskyrong commented May 30, 2018

合并 #307

说明

导出。。不要使用前端实现方式。。使用后端实现。
否则你会遇到各种问题,数不胜数:

  • 文字编码,中文编码,各种乱码
  • excel的格式,xls的格式兼容
  • 分页、全部数据
  • 数据量过大导致前端阻塞,从而导致浏览器崩溃

提供一个解决思路

前端

  1. 把对应的“导出”按钮做成一个链接
  2. 点击按钮,跳转到对应链接 /source/download ,带上各种过滤条件(offset+limit和其他业务查询条件),其为静态资源地址,此时浏览器会自动开启下载

后端

  1. 后端拦截到 /source/download 的路由请求后,将链接对应的数据(链接中可以带一定的参数来完成查询SQL的拼接,诸如offset/limit等)进行DB查询
  2. 直接用后端语言(java、NodeJS)调用对应Excel扩展包,整合成一个所需格式(excelxls等)的文件 /public/download/xxx.xls
  3. 然后转发(redirect) /source/download 链接请求到 /public/download/xxx.xls

几点说明:

1、 一定、不要在前端完成全量数据的拼接,数据拉取过程中极有可能timeout
2、因为是分页服务端server-side模式,每次的数据量都是小量,一旦全量下载,后端拼装完成后的excel文件大小和传输方式(文件流)比前端使用ajax或其他下载方式美好太多。。。

@occultskyrong
Copy link
Collaborator

occultskyrong commented May 30, 2018

同样,你这个问题。。后端用excel扩展包,分分钟解决。
如果后端是nodeJS
npm下很多这种包

https://github.com/mgcrea/node-xlsx

如果是java,自己扒拉扒拉jar包

@occultskyrong
Copy link
Collaborator

occultskyrong commented Oct 26, 2018

NodeJS中一个非常牛逼、有效的module - csv

具体参见 https://www.npmjs.com/package/csv

大体的示例代码,可有效解决Macwindowsexcel使用GBK编码,而Node使用UTF-8编码的问题

    const stringify = require('csv-stringify/lib/sync');
    const { Iconv } = require('iconv');
      
    // data 为原始数据
    // columns 为excel的自定义头部,具体见csv中header和columns的说明
    const json = await stringify(data, { header: true, columns });
    const iconv = new Iconv('UTF-8', 'GBK//IGNORE'); // 定义buffer的转码器
    const content = iconv.convert(json);
    const filename = iconv.convert('中文文件名.csv').toString('binary');
    res.setHeader('Pragma', 'public');
    res.setHeader('Expires', '0');
    res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
    res.setHeader('Content-Type', 'text/csv; charset=GBK');
    res.setHeader('Content-Disposition', 'attachment;filename="' + filename + '"');
    res.setHeader('Content-Length', content.length);
    res.end(content);

@occultskyrong
Copy link
Collaborator

归档所有跟导出有关的问题


本身导出问题,完全可以交给后端去实现,前端可以不考虑。
如有特殊原因,请追问。


#15
#35
#65
#95
#195
#224
#307
#384
#403
#418
#425


其他跟导出有关的issue

#380 » dataTables导出excel,复杂表头显示不全
#391 » excel 想要导出页面的图片怎么处理
#405 » 怎样使得导出到excel中的内容不包含有隐藏列的数据呢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Essence 精华 √Solved 已解决
Projects
None yet
Development

No branches or pull requests

2 participants