为什么要使用js-xlsx呢?
假如我们遇到了这样一个需求,把数据库中的数据导出位Excel,或者把Excel导入到数据库(这里以导出Excel为例).
前端导出演示
[后端暂无]
点击查看Javascripts把Excel解析为json(js-xlsx)
前端解决方案:Js-Xlsx
这里以 json转换为Excel为例
前提
- 数据必须符合json规范
导出主要分为3个步骤
- 创建一个工作簿
- 通过json数据创建一个表
- 把表添加到工作簿
- 最后写出文件
//创建一个工作簿
let wb = XLSX.utils.book_new();
//通过json数据创建一个表(sheet)
let ws = XLSX.utils.json_to_sheet(tmpArr);
//把表添加到工作簿
XLSX.utils.book_append_sheet(wb, ws, "sheet1");
//把工作簿写出到文件(第二个参数为文件名称)
XLSX.writeFile(wb, "用户订单.xlsx");
后端解决方案(POI)
把对象/对象列表导出大体分为如下步骤
- 得到数据
- 创建工作簿
- 创建sheet工作表
- 设置表头信息(非必需)
- 设置其每个单元格的数据
一下是代码
@RequestMapping("/poi")
public ResponseEntity<byte[]> excelDownload(HttpServletResponse response) {
//通过条件匹配得到数据
Map<String, String> searchEntity = new HashMap<>();
searchEntity.put("isMarketable", "");
searchEntity.put("auditStatus", "");
searchEntity.put("currentPage", "");
searchEntity.put("pageSize", "");
PageResult<TbGoods> res = goodsService.matchGoodsPage(searchEntity);
List<TbGoods> tbGoods = res.getRows();
//得到数据完成, tbGoods就是我们的数据,接下来我们就需要将其导出为excel
//创建一个工作簿
XSSFWorkbook wb = new XSSFWorkbook();
//创建一个sheet(工作表)
XSSFSheet ws = wb.createSheet();
//设置(表头数据,非必需)
XSSFRow row = ws.createRow(0);
Class<TbGoods> tbGoodsClass = TbGoods.class;
Field[] fields = tbGoodsClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);
String name = fields[i].getName();
row.createCell(i).setCellValue(name);
}
//表头数据结束
setCellValue(ws,tbGoods,tbGoodsClass);//设置单元格数据
//下载文件
try {
String fileName = new String("商品所有数据".getBytes("gbk"), "iso8859-1");
// 设置导出文件的格式 MIMETYPE
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
// 设置导出文件名
response.setHeader("Content-Disposition", "attachment;filename=emp.xlsx");
ServletOutputStream outputStream = response.getOutputStream();
wb.write(outputStream);
} catch (Exception e) {
}
return null;
}
//反射设置每个单元格的内容
private <T> void setCellValue(XSSFSheet sheet,List<T> data,Class<T> clazz) {
//先获取所有的字段和方法
Method[] methods = clazz.getMethods();
Field[] fields = clazz.getDeclaredFields();
//循环并设置
for (int i = 1; i <= data.size(); i++) {//每条数据一行
XSSFRow tmpRow = sheet.createRow(i);//行
for (int j = 0; j < fields.length; j++) {
String val = invokeAfterValue(fields[j], methods, data.get(i-1));
tmpRow.createCell(j).setCellValue(val);//createCell的索引应该是列的索引,值因该是调用的值
}
}
}
//反射调用get方法得到的结果,被单元格设置值调用
private <T> String invokeAfterValue(Field field,Method[] methods,T t) {
for (int i = 0; i < methods.length; i++) {
field.setAccessible(true);
if (methods[i].getName().equalsIgnoreCase("get"+field.getName())) {
try {
String res = methods[i].invoke(t)+"";
return res;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return null;
}