爲什麼要使用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;
}