poi處理excel遇到的坑
阿新 • • 發佈:2019-02-05
做poi匯入匯出:
匯出功能還好比較簡單,只需要指定好相應模板,對於日期格式的資料來說,同理模板需要設定日期,然後模板中大致的格式是
<jx:forEach items="${itsmciList}" var="itsmci"> | ||||
${itsmci.name} | ${itsmci.categoryvalue} | ${itsmci.version} | ${itsmci.sn} | ${itsmci.assetNumber} |
</jx:forEach> |
poi從資料庫------到excel:原理是,先讀模板,往模板注入資料,形成Workbook,workbooke經ServletOutputStream,流到瀏覽器端。
直接上程式碼:
匯出 @RequestMapping("/itsmciExport.do") public void itsmciExport(HttpServletRequest request,HttpServletResponse response) throws IOException, ParsePropertyException, InvalidFormatException { QueryParameter paramMap = new QueryParameter(); paramMap.addEquals("companyid", getUser().getCompanyId()); List<Itsm_ci> list = itsm_ciService.findListByParam(paramMap); if(CollectionUtils.isNotEmpty(list)){ String companyId = list.get(0).getCompanyid(); Itsm_ci.formatList(companyId, list);//翻譯 } itsmCiFeatureproService.getFeatureproInfor(list); //加進特徵資訊 String fileName = getUser().getCompanyName()+"的配置項.xls"; String filePath = this.getClass().getClassLoader().getResource("//templates//itsmciList.xls").getPath(); Map<String, Object> beans = new HashMap<String, Object>(); beans.put("itsmciList", list); InputStream is = new BufferedInputStream(new FileInputStream(filePath)); XLSTransformer transformer = new XLSTransformer(); Workbook resultWorkbook = transformer.transformXLS(is, beans); is.close(); super.responseDownloadWorkbook(request, response, fileName, resultWorkbook); }
匯出完畢;/** * workbook檔案下載方法 * * @param response * @param fileName * 檔名 * @param workbook * 檔案 * @throws IOException */ public void responseDownloadWorkbook(HttpServletRequest request, HttpServletResponse response, String fileName, Workbook workbook) throws IOException { String agent = request.getHeader("User-Agent").toUpperCase(); String encodedfileName = ""; if (agent.indexOf("MSIE") != -1 || agent.indexOf("TRIDENT") != -1) { // IE encodedfileName = URLEncoder.encode(fileName, "utf-8"); } else if (agent.indexOf("CHROME") != -1 || agent.indexOf("FIREFOX") != -1) { // 谷歌或火狐 encodedfileName = new String(fileName.getBytes("utf-8"), "ISO8859-1"); } else { encodedfileName = new String(fileName.getBytes("utf-8"), "ISO8859-1"); } // 設定輸出的格式 response.reset(); response.setContentType("bin"); response.addHeader("Content-Disposition", "attachment; filename=\"" + encodedfileName + "\""); // 取出流中的資料 ServletOutputStream os = response.getOutputStream(); workbook.write(os); os.write(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF });// UTF-8 os.flush(); os.close(); }
匯入功能:我的需求比較複雜:需要根據 填寫欄位的名稱去找外來鍵 ,excel中填的是名稱,但是存到資料庫中是外來鍵(前提是該名稱在主表中已經存在),然後還需要分析excel填寫的資訊的合法性,並且將錯誤資訊返回給使用者(這裡需要判斷多個欄位唯一性,對資料庫中不存在的主表字段,也要報錯誤,這裡我是用List<>來存放錯誤)。
然後一個很特別的坑是日期格式的資料。(注意,excel匯入到資料庫的功能:一般情況下需要伺服器制定好模板讓使用者去下載,然後填寫。所以製作模板的時候將時間格式的資料設定為時間格式)
具體業務就不寫了,把那個坑獻上:
/**
*
*author:cwy
*說明:將excel表中的資料倒入到資料庫時要用到,將excel表中的資料轉換成List<Map<String,Object>>形式的資料
*引數:
* @param in 輸入流
* @param filename 檔案原始名字
* @param startrow 從第幾行開始讀
* @param startcol 從第幾列開始讀
* @param sheetnum 第幾個sheet開始
* @return
* @throws IOException
*/
public List<Map<String,Object>> readAllExcel(InputStream in, String filename, int startrow, int startcol, int sheetnum) throws IOException {
List<Map<String,Object>> varList = new ArrayList<Map<String,Object>>();
Workbook wb=null;
try {
if(filename.substring(filename.lastIndexOf(".")+1).equals("xlsx"))
{
wb = new XSSFWorkbook(in);
}
else
{
wb=new HSSFWorkbook(in);
}
Sheet sheet = wb.getSheetAt(sheetnum); // sheet 從0開始
int rowNum = sheet.getLastRowNum() + 1; // 取得最後一行的行號
for (int i = startrow; i < rowNum; i++) { // 行迴圈開始
Row row = sheet.getRow(i); // 行
int cellNum = row.getLastCellNum(); // 每行的最後一個單元格位置
Map<String,Object> map=new HashMap<String,Object>();
for (int j = startcol; j < cellNum; j++) { // 列迴圈開始
Cell cell = row.getCell(Short.parseShort(j + ""));
String cellValue = null;
if (null != cell) {
switch (cell.getCellType()) { // 判斷excel單元格內容的格式,並對其進行轉換,以便插入資料庫
case 0: //數字型別(包括純數字和時間)
cellValue = String.valueOf((int) cell.getNumericCellValue());
if(HSSFDateUtil.isCellDateFormatted(cell)) //如果是時間格式(萬能方法)
{
short format = cell.getCellStyle().getDataFormat();
SimpleDateFormat sdf = null;
if(format == 14 || format == 31 || format == 57 || format == 58){
//日期
sdf = new SimpleDateFormat("yyyy-MM-dd");
}else if (format == 20 || format == 32) {
//時間
sdf = new SimpleDateFormat("HH:mm");
}
double value = cell.getNumericCellValue();
Date date = DateUtil.getJavaDate(value);
cellValue = sdf.format(date);
}
break;
case 1: //字串型別
cellValue = cell.getStringCellValue();
break;
case 2: //格式型別
cellValue = cell.getNumericCellValue() + "";
break;
case 3: //空
cellValue = "";
break;
case 4: //布林型別
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case 5: //錯誤
cellValue = String.valueOf(cell.getErrorCellValue());
break;
}
} else {
cellValue = "";
}
map.put("var"+j,cellValue);
}
varList.add(map);
}
} catch (Exception e) {
System.out.println(e);
}
finally{in.close();}
return varList;
}
List<Map<String,Object>> excel的資料就全放到這裡了。後面是解析和儲存。