最近項目中需要將table 中數據導出到excel ,當時我想的兩種方案,一種是通過前端插件TableExport.js。發現簡單使用的話,只是可以導出table 中原生的數據。一旦table 有jstl 標籤判斷的話,它讀不到。最後採取通過服務端到來實現導出Excel 格式是.xlsx。這個方案可以導出大量的數據。分頁顯示。核心代碼如下;
1、這個公用的方法不帶表頭標題的。
/**
* 不帶表頭的Excel
* @param title
* @param headMap
* @param jsonArray
* @param datePattern
* @param colWidth
* @param out
*/
public static void exportToExcel(Map<String, String> headMap,JSONArray jsonArray,String datePattern,int colWidth, OutputStream out) {
if(datePattern==null) datePattern = DEFAULT_DATE_PATTERN;
// 聲明一個工作薄
SXSSFWorkbook workbook = new SXSSFWorkbook(1000);//緩存
workbook.setCompressTempFiles(true);
// 生成一個表格
SXSSFSheet sheet = workbook.createSheet();
//設置列寬
int minBytes = colWidth<DEFAULT_COLOUMN_WIDTH?DEFAULT_COLOUMN_WIDTH:colWidth;//至少字節數
int[] arrColWidth = new int[headMap.size()];
// 產生表格標題行,以及設置列寬
String[] properties = new String[headMap.size()];
String[] headers = new String[headMap.size()];
int ii = 0;
for (Iterator<String> iter = headMap.keySet().iterator(); iter
.hasNext();) {
String fieldName = iter.next();
properties[ii] = fieldName;
headers[ii] = headMap.get(fieldName);
int bytes = fieldName.getBytes().length;
arrColWidth[ii] = bytes < minBytes ? minBytes : bytes;
sheet.setColumnWidth(ii,arrColWidth[ii]*256);
ii++;
}
// 遍歷集合數據,產生數據行
int rowIndex = 0;
for (Object obj : jsonArray) {
if(rowIndex == 65535 || rowIndex == 0){
if ( rowIndex != 0 ) sheet = workbook.createSheet();//如果數據超過了,則在第二頁顯示
SXSSFRow headerRow = sheet.createRow(0); //列頭 rowIndex =1
for(int i=0;i<headers.length;i++)
{
headerRow.createCell(i).setCellValue(headers[i]);
}
rowIndex = 1;//數據內容從 rowIndex=1開始
}
JSONObject jo = (JSONObject) JSONObject.toJSON(obj);
SXSSFRow dataRow = sheet.createRow(rowIndex);
for (int i = 0; i < properties.length; i++)
{
SXSSFCell newCell = dataRow.createCell(i);
Object o = jo.get(properties[i]);
String cellValue = "";
if(o==null) cellValue = "";
else if(o instanceof Date) cellValue = new SimpleDateFormat(datePattern).format(o);
else if(o instanceof Float || o instanceof Double)
cellValue= new BigDecimal(o.toString()).setScale(2,BigDecimal.ROUND_HALF_UP).toString();
else cellValue = o.toString();
newCell.setCellValue(cellValue);
}
rowIndex++;
}
// 自動調整寬度
sheet.trackAllColumnsForAutoSizing();
for (int i = 0; i < headers.length; i++) {
sheet.autoSizeColumn(i);
}
try {
workbook.write(out);
workbook.close();
boolean flag = workbook.dispose();//釋放磁盤空間。處理在磁盤上支持這個工作簿的臨時文件。調用該方法將使工作簿不可用。
System.out.println(flag);//如果所有臨時文件都被成功刪除,則爲真。
} catch (IOException e) {
e.printStackTrace();
}
}
2、如何調用。
/**
* 整合數據導出到Excle
*
* @param response
* @param userApplyMap
*/
public void exportExcle(HttpServletResponse response, List<Map<String, Object>> userApplyMap) {
ServletOutputStream outputStream = null;
FileInputStream fileInputStream = null;
String toDir = null;
try {
JSONArray userApplyInfos = new JSONArray();
if (!userApplyMap.isEmpty()) {// 數據集
for (Map<String, Object> map : userApplyMap) {
com.alibaba.fastjson.JSONObject userApply = new com.alibaba.fastjson.JSONObject();
userApply.put("userName", map.get("userName"));
userApply.put("bankOpeningName", map.get("bankOpeningName"));
userApply.put("expenditure", map.get("expenditure"));
userApply.put("amount", map.get("amount"));
userApply.put("serviceFee", map.get("serviceFee"));
userApply.put("bankNo", map.get("bankNo"));
userApply.put("withdraw", getWithdrawOrStatus(map, 1));
userApply.put("bankOpening", new StringBuilder(
map.get("bankOpening").toString() + "\n" + map.get("bankName").toString()));
userApply.put("status", getWithdrawOrStatus(map, 2));
userApply.put("addTime",
DateFormat.getFormatNowTime(Long.parseLong(map.get("addTime").toString()), null));
userApplyInfos.add(userApply);
}
Map<String, String> headMap = new LinkedHashMap<String, String>();// 存放表頭部信息
headMap.put("userName", "賬號");
headMap.put("bankOpeningName", "收款人");
headMap.put("expenditure", "金額");
headMap.put("amount", "金額");
headMap.put("serviceFee", "手續費");
headMap.put("bankNo", "賬戶");
headMap.put("withdraw", "方式");
headMap.put("bankOpening", "信息");
headMap.put("status", "狀態");
headMap.put("addTime", "申請時間");
Random random = new Random();
String title = "提現信息";
// 生成文件臨時存放目錄
toDir = QuzuUtils.getInstance().getDir(random);
String path = new StringBuffer().append(toDir).append(title).append(QuzuConst.TYPE_ARRAY[0]).toString();
OutputStream outXlsx = new FileOutputStream(path);
ExcelUtil.exportToExcel(headMap, userApplyInfos, null, 0, outXlsx);
outXlsx.close();
response.setHeader("Content-Disposition", "attachment;filename="
+ new String((title + QuzuConst.TYPE_ARRAY[0]).getBytes(), "iso-8859-1"));
outputStream = response.getOutputStream();
fileInputStream = new FileInputStream(path);
byte[] bytes = new byte[1024];
int size;
while (-1 != (size = fileInputStream.read(bytes))) {
outputStream.write(bytes, 0, size);
}
outputStream.flush();
} else {
ResponseUtil.write(response, "暫無數據可導出");
}
} catch (Exception e) {
logger.error("導出提現信息異常", e);
} finally {
if (fileInputStream != null)
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
if (outputStream != null)
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 刪除臨時文件
Utils.getInstance().deleteTempFiles(toDir);
}
/**
* 導出excle
*
* @param userApplySearchVo
* @param request
* @param response
*/
@RequestMapping("/exportInfo")
public void exportInfo(UserApplySearchVo userApplySearchVo, HttpServletRequest request,
HttpServletResponse response) {
try {
Map<String, Object> params = new HashMap<>();
creatParams(userApplySearchVo, params);
List<Map<String, Object>> userAccountApplies = userAccountApplyManageService.selectListWithUserName(params);//查出需要導出的數據
exportExcle(response, userAccountApplies);//這裏調用
} catch (Exception e) {
logger.error("查詢列表異常", e);
}
}
3、效果圖,號碼隨便抓的就打碼。