poi批量匯入匯出Excel(一、需要建資料庫表)
阿新 • • 發佈:2019-01-04
本專案基於SSM框架,簡單封裝了Excel批量匯入匯出功能,需要建資料庫表將資料匯入到表中,查詢遍歷出資料匯出Excel,下一篇文章介紹下不用建資料庫表一鍵匯入匯出Excel(點選跳轉),不過這樣只適用於對匯入的Excel表進行轉換。
一、下載poi jar包:
點這裡下載:poi 3.8/3.9/3.10三個版本下載
poi 3.17最新版本下載
二、基本操作步驟:
首先,理解一下一個Excel的檔案的組織形式,一個Excel檔案對應於一個workbook(HSSFWorkbook),一個workbook可以有多個sheet(頁/表)(HSSFSheet)組成,一個sheet是由多個row(行)(HSSFRow)組成,一個row是由多個cell(單元格)(HSSFCell)組成。
1、用HSSFWorkbook開啟或者建立“Excel檔案物件”
2、用HSSFWorkbook物件返回或者建立Sheet物件
3、用Sheet物件返回行物件,用行物件得到Cell物件
4、對Cell物件讀寫。
三、封裝Excel工具類ImportExcelUtil
public class ImportExcelUtil { private final static String Excel_2003 = ".xls"; //2003 版本的excel private final static String Excel_2007 = ".xlsx"; //2007 版本的excel /** * @param in * @param fileName * @param columNum 自定義列數 * @return * */ public List<List<Object>> getBankListByExcel(InputStream in,String fileName) throws Exception{ List<List<Object>> list = null; //建立Excel工作簿 Workbook work = this.getWorkbook(in, fileName); if(work == null) { throw new Exception("建立Excel工作簿為空!"); } Sheet sheet = null; Row row = null; Cell cell = null; list = new ArrayList<List<Object>>(); //遍歷Excel中的所有sheet for(int i = 0; i<work.getNumberOfSheets(); i++) { sheet = work.getSheetAt(i); if(sheet == null) {continue;} //遍歷當前sheet中的所有行 //int totalRow = sheet.getPhysicalNumberOfRows();//如果excel有格式,這種方式取值不準確 int totalRow = sheet.getPhysicalNumberOfRows(); for(int j = sheet.getFirstRowNum(); j<totalRow; j++) { row = sheet.getRow(j); if(!isRowEmpty(row)) { //if(row != null && !"".equals(row)) { //獲取第一個單元格的資料是否存在 Cell fristCell=row.getCell(0); if(fristCell!=null){ //遍歷所有的列 List<Object> li = new ArrayList<Object>(); //int totalColum = row.getLastCellNum(); for(int y = row.getFirstCellNum(); y<row.getLastCellNum(); y++) { cell = row.getCell(y); String callCal = this.getCellValue(cell)+""; li.add(callCal); } list.add(li); } }else if(isRowEmpty(row)){ continue; } } } in.close(); return list; } /** * 判斷行是否為空 * @param row * @return */ public static boolean isRowEmpty(Row row) { for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) { Cell cell = row.getCell(c); if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK) return false; } return true; } /** * 描述:根據檔案字尾,自動適應上傳檔案的版本 * @param inStr,fileName * @return * @throws Exception * */ public Workbook getWorkbook(InputStream inStr,String fileName) throws Exception { Workbook work = null; String fileType = fileName.substring(fileName.lastIndexOf(".")); if(Excel_2003.equals(fileType)){ work=new HSSFWorkbook(inStr);//2003 版本的excel }else if(Excel_2007.equals(fileType)) { work=new XSSFWorkbook(inStr);//2007 版本的excel }else { throw new Exception("解析檔案格式有誤!"); } return work; } /** * 描述:對錶格中數值進行格式化 * @param cell * @return * */ public Object getCellValue(Cell cell) { /*Object value = null; DecimalFormat df1 = new DecimalFormat("0.00");//格式化number,string字元 SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");//日期格式化 DecimalFormat df2 = new DecimalFormat("0.00");//格式化數字 if(cell !=null && !"".equals(cell)) { switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: value = cell.getRichStringCellValue().getString(); break; case Cell.CELL_TYPE_NUMERIC: if("General".equals(cell.getCellStyle().getDataFormatString())) { value = df1.format(cell.getNumericCellValue()); }else if("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) { value = sdf.format(cell.getDateCellValue()); }else if(HSSFDateUtil.isCellDateFormatted(cell)){ Date date = cell.getDateCellValue(); value = sdf.format(date); } else { value = df2.format(cell.getNumericCellValue()); } break; case Cell.CELL_TYPE_BOOLEAN: value = cell.getBooleanCellValue(); break; case Cell.CELL_TYPE_BLANK: value = ""; break; default: break; } } return value;*/ String result = new String(); switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_FORMULA: //Excel公式 try { result = String.valueOf(cell.getNumericCellValue()); } catch (IllegalStateException e) { result = String.valueOf(cell.getRichStringCellValue()); } break; case HSSFCell.CELL_TYPE_NUMERIC:// 數字型別 if (HSSFDateUtil.isCellDateFormatted(cell)) {// 處理日期格式、時間格式 SimpleDateFormat sdf; if (cell.getCellStyle().getDataFormat() == HSSFDataFormat .getBuiltinFormat("h:mm")) { sdf = new SimpleDateFormat("HH:mm"); } else {// 日期 sdf = new SimpleDateFormat("yyyy-MM-dd"); } Date date = cell.getDateCellValue(); result = sdf.format(date); } else if (cell.getCellStyle().getDataFormat() == 58) { // 處理自定義日期格式:m月d日(通過判斷單元格的格式id解決,id的值是58) SimpleDateFormat sdf = new SimpleDateFormat("M月d日"); double value = cell.getNumericCellValue(); Date date = org.apache.poi.ss.usermodel.DateUtil .getJavaDate(value); result = sdf.format(date); } else { double value = cell.getNumericCellValue(); CellStyle style = cell.getCellStyle(); DecimalFormat format = new DecimalFormat(); String temp = style.getDataFormatString(); // 單元格設定成常規 if (temp.equals("General")) { format.applyPattern("#.##"); } result = format.format(value); } break; case HSSFCell.CELL_TYPE_STRING:// String型別 result = cell.getRichStringCellValue().toString(); break; case HSSFCell.CELL_TYPE_BLANK: result = ""; default: result = ""; break; } return result; } public String getFormat(String str) { if(str.equals("null")) { str=""; return str; }else{ return str; } } public Integer getFormats(Integer str) { if(str==null) { str=0; return str; }else{ return str; } } /** * 獲取字串中的數字訂單號、數字金額等,如從"USD 374.69"中獲取到374.69、從“交易單號:66666666666”獲取到66666666666 * @param receiptAmountString * @return */ public static String getFormatNumber(String str){ str = str.trim(); Pattern p = Pattern.compile("[0-9]"); int indexNum = 0; int lenght = str.length(); String num = ""; for(int i=0;i<lenght;i++){ num += str.charAt(i); Matcher m = p.matcher(num); if(m.find()){ indexNum = i; break; } } String formatNumber = str.substring(indexNum,lenght); return formatNumber; } }
四、控制層Controller匯入匯出
/** * 匯入銷售訂單資料 * @param myFile * @param respon * @return * @throws IOException */ @RequiresPermissions("orderexcel:orderexcel:edit") @RequestMapping(value = "import", method=RequestMethod.POST) public String importFile(Orderexcel order, @RequestParam(value="file",required=false)MultipartFile myFile,HttpServletResponse respon,RedirectAttributes redirectAttributes) throws IOException { try { //先刪除資料庫原有的資料 orderexcelService.deleteAll(order); ImportExcelUtil util = new ImportExcelUtil(); InputStream input = null; List<List<Object>> lists = null; if (myFile.isEmpty()) { addMessage(redirectAttributes, "匯入檔案為空,請先新增Excel檔案!"); } else { // 如果錯誤為0 String fileName = myFile.getOriginalFilename(); input = myFile.getInputStream(); lists = util.getBankListByExcel(input, fileName); input.close(); // 迴圈將excel中的資料存入庫 for (int i = 1; i < lists.size(); i++) { List<Object> list = lists.get(i); Orderexcel orderexcel = new Orderexcel(); orderexcel.setDate(util.getFormat(String.valueOf(list.get(0)))); orderexcel.setOrdernumber(util.getFormat(String.valueOf(list.get(1)))); orderexcel.setInternumber(util.getFormat(String.valueOf(list.get(2)))); orderexcel.setCountrynumber(util.getFormat(String.valueOf(list.get(3)))); orderexcel.setTevonumber(util.getFormat(String.valueOf(list.get(4)))); orderexcel.setCustomernumber(util.getFormat(String.valueOf(list.get(5)))); orderexcel.setRemarks(util.getFormat(String.valueOf(list.get(6)))); orderexcel.setProductnumber(util.getFormat(String.valueOf(list.get(7)))); orderexcel.setSku(util.getFormat(String.valueOf(list.get(8)))); orderexcel.setNumber(util.getFormat(String.valueOf(list.get(9)))); orderexcel.setTaxprice(util.getFormat(String.valueOf(list.get(10)))); orderexcel.setTotalprice(util.getFormat(String.valueOf(list.get(11)))); orderexcel.setCurrency(util.getFormat(String.valueOf(list.get(12))));//幣種 orderexcel.setExchangerate(util.getFormat(String.valueOf(list.get(13))));//匯率 orderexcel.setAddress(util.getFormat(String.valueOf(list.get(14))));//地址 orderexcel.setCountry(util.getFormat(String.valueOf(list.get(15))));//國家 orderexcel.setPlug(util.getFormat(String.valueOf(list.get(16)))); orderexcel.setInterfreightforwarder(util.getFormat(String.valueOf(list.get(17)))); orderexcel.setCountryfreightforwarder(util.getFormat(String.valueOf(list.get(18)))); orderexcel.setSalesmannumber(util.getFormat(String.valueOf(list.get(19)))); orderexcel.setSalesman(util.getFormat(String.valueOf(list.get(20)))); orderexcel.setIntercoursenumber(util.getFormat(String.valueOf(list.get(21)))); orderexcel.setIntercourse(util.getFormat(String.valueOf(list.get(22)))); orderexcel.setOfficenumber(util.getFormat(String.valueOf(list.get(23)))); orderexcel.setWarehousenumber(util.getFormat(String.valueOf(list.get(24))));//倉庫編碼 orderexcelService.save(orderexcel); } } } catch (Exception e) { e.printStackTrace(); addMessage(redirectAttributes, "匯入檔案異常請檢查Excel檔案!"); } return "redirect:" + adminPath + "/orderexcel/orderexcel/list?repage"; } /** * 匯出跟單資訊Excel表 * * @author * */ @RequiresPermissions("sys:user:view") @RequestMapping(value = "export", method=RequestMethod.POST) public void exportallDocumentaryExcel(Orderexcel orderexcel,HttpServletResponse response, HttpServletRequest res,RedirectAttributes redirectAttributes) throws IOException { try { List<Orderexcel> docuList = orderexcelService.findList(orderexcel); if (docuList.size() == 0) { addMessage(redirectAttributes, "未查到資料,請先匯入Excel檔案"); } else { // 在記憶體中建立一個Excel檔案,通過輸出流寫到客戶端提供下載 // 記憶體中保留 10000 條資料,以免記憶體溢位,其餘寫入 硬碟 SXSSFWorkbook workbook = new SXSSFWorkbook(10000); CellStyle style = workbook.createCellStyle(); style.setAlignment(XSSFCellStyle.ALIGN_CENTER);//SXSSFWorkbook方式的居中 // 建立一個sheet頁 SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet("銷售訂單"); // 分別設定Excel列的寬度 /*sheet.setColumnWidth(0, 100 * 40); // 單據日期*/ // 建立標題 SXSSFRow headRow = (SXSSFRow) sheet.createRow(0); headRow.createCell(0).setCellValue("單據日期"); headRow.createCell(1).setCellValue("單據編號"); headRow.createCell(2).setCellValue("客戶編碼"); headRow.createCell(3).setCellValue("客戶"); headRow.createCell(4).setCellValue("結算客戶編碼"); headRow.createCell(5).setCellValue("結算客戶"); headRow.createCell(6).setCellValue("部門編碼"); headRow.createCell(7).setCellValue("部門"); headRow.createCell(8).setCellValue("業務員編碼"); headRow.createCell(9).setCellValue("業務員"); headRow.createCell(10).setCellValue("幣種程式碼"); headRow.createCell(11).setCellValue("幣種"); headRow.createCell(12).setCellValue("匯率"); headRow.createCell(13).setCellValue("運輸方式"); headRow.createCell(14).setCellValue("送貨地址"); headRow.createCell(15).setCellValue("聯絡人"); headRow.createCell(16).setCellValue("聯絡電話"); headRow.createCell(17).setCellValue("客戶手機號"); headRow.createCell(18).setCellValue("合同號"); headRow.createCell(19).setCellValue("收款方式"); headRow.createCell(20).setCellValue("外部單據號"); headRow.createCell(21).setCellValue("按倉庫拆單出庫"); headRow.createCell(22).setCellValue("國際單號"); headRow.createCell(23).setCellValue("內部單號"); headRow.createCell(24).setCellValue("備註"); headRow.createCell(25).setCellValue("倉庫編碼"); headRow.createCell(26).setCellValue("倉庫"); headRow.createCell(27).setCellValue("專案編碼"); headRow.createCell(28).setCellValue("專案"); headRow.createCell(29).setCellValue("存貨編碼"); headRow.createCell(30).setCellValue("存貨名稱"); headRow.createCell(31).setCellValue("銷售單位"); headRow.createCell(32).setCellValue("數量"); headRow.createCell(33).setCellValue("報價"); headRow.createCell(34).setCellValue("折扣%"); headRow.createCell(35).setCellValue("稅率%"); headRow.createCell(36).setCellValue("含稅單價"); headRow.createCell(37).setCellValue("含稅金額"); headRow.createCell(38).setCellValue("預計交貨日期"); headRow.createCell(39).setCellValue("贈品"); headRow.createCell(40).setCellValue("備註"); headRow.createCell(41).setCellValue("國家"); headRow.createCell(42).setCellValue("貨代"); headRow.createCell(43).setCellValue("客戶單號"); for (Orderexcel docu : docuList) { // 建立行 SXSSFRow dataRow = (SXSSFRow) sheet.createRow(sheet.getLastRowNum() + 1); dataRow.createCell(0).setCellValue(docu.getDate());//單據日期 dataRow.createCell(1).setCellValue(docu.getOrdernumber());//單據編號(內部單號) dataRow.createCell(2).setCellValue(docu.getIntercoursenumber());//往來單位編碼(客戶編碼)(結算客戶編碼) dataRow.createCell(3).setCellValue("");//客戶 dataRow.createCell(4).setCellValue(docu.getIntercoursenumber());//結算客戶編碼 dataRow.createCell(5).setCellValue("");//結算客戶 dataRow.createCell(6).setCellValue(docu.getOfficenumber());//部門編碼 dataRow.createCell(7).setCellValue("");//部門 dataRow.createCell(8).setCellValue(docu.getSalesmannumber());//業務員編碼 dataRow.createCell(9).setCellValue(docu.getSalesman());//業務員 dataRow.createCell(10).setCellValue(docu.getCurrency());//幣種程式碼 dataRow.createCell(11).setCellValue("");//幣種 dataRow.createCell(12).setCellValue(docu.getExchangerate());//匯率 dataRow.createCell(13).setCellValue("");//運輸方式 dataRow.createCell(14).setCellValue("");//送貨地址 dataRow.createCell(15).setCellValue("");//聯絡人 dataRow.createCell(16).setCellValue("");//聯絡電話 dataRow.createCell(17).setCellValue("");//客戶手機號 dataRow.createCell(18).setCellValue("");//合同號 dataRow.createCell(19).setCellValue("其它");//收款方式 dataRow.createCell(20).setCellValue("");//外部單據號 dataRow.createCell(21).setCellValue("");//按倉庫拆單出庫 dataRow.createCell(22).setCellValue("");//國際單號 dataRow.createCell(23).setCellValue(docu.getnumber());//內部單號 dataRow.createCell(24).setCellValue(docu.getRemarks());//備註 dataRow.createCell(25).setCellValue(docu.getWarehousenumber());//倉庫編碼 dataRow.createCell(26).setCellValue("");//倉庫 dataRow.createCell(27).setCellValue("");//專案編碼 dataRow.createCell(28).setCellValue("");//專案 dataRow.createCell(29).setCellValue(docu.getSku());//存貨編碼 dataRow.createCell(30).setCellValue("");//存貨名稱 dataRow.createCell(31).setCellValue("個");//銷售單位 dataRow.createCell(32).setCellValue(docu.getNumber());//數量 dataRow.createCell(33).setCellValue("");//報價 dataRow.createCell(34).setCellValue("");//折扣% dataRow.createCell(35).setCellValue("0");//稅率% dataRow.createCell(36).setCellValue(docu.getTaxprice());//含稅單價 dataRow.createCell(37).setCellValue(docu.getTotalprice());//含稅金額 dataRow.createCell(38).setCellValue("");//預計交貨日期 dataRow.createCell(39).setCellValue("");//贈品 dataRow.createCell(40).setCellValue("");//備註 dataRow.createCell(41).setCellValue(docu.getCountry());//國家 dataRow.createCell(42).setCellValue(docu.getInterfreightforwarder());//貨代?國際 dataRow.createCell(43).setCellValue(docu.getCustomernumber());//客戶單號 } // 設定Excel檔名,並以中文進行編碼 String codedFileName = new String("銷售訂單".getBytes("gbk"), "iso-8859-1"); response.setHeader("Content-Disposition", "attachment;filename=" + codedFileName + DateUtils.getDate("yyyyMMddHHmmss") +".xlsx"); // 響應型別,編碼 response.setContentType("application/octet-stream;charset=UTF-8"); // 形成輸出流 OutputStream osOut = response.getOutputStream(); // 將指定的位元組寫入此輸出流 workbook.write(osOut); // 重新整理此輸出流並強制將所有緩衝的輸出位元組被寫出 osOut.flush(); // 關閉流 osOut.close(); /* * dispose of temporary files backing this workbook on disk * 處理在磁碟上備份此工作簿的臨時檔案 SXSSF分配臨時檔案,您必須始終清除顯式,通過呼叫dispose方法 */ workbook.dispose(); } } catch (Exception e) { e.printStackTrace(); addMessage(redirectAttributes, "匯出使用者失敗!失敗資訊:"+e.getMessage()); } }
五、jsp頁面
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
<html>
<head>
<title>銷售訂單表匯入匯出管理</title>
<meta name="decorator" content="default"/>
<script type="text/javascript">
/* $(document).ready(function() {
}); */
$(document).ready(function() {
$("#btnExport").click(function(){
top.$.jBox.confirm("確認要匯出使用者資料嗎?","系統提示",function(v,h,f){
if(v=="ok"){
$("#searchForm").attr("action","${ctx}/orderexcel/orderexcel/export");
$("#searchForm").submit();
}
},{buttonsFocus:1});
top.$('.jbox-body .jbox-icon').css('top','55px');
});
$("#btnImport").click(function(){
$.jBox($("#importBox").html(), {title:"匯入資料", buttons:{"關閉":true},
bottomText:"匯入檔案不能超過5M,僅允許匯入“xls”或“xlsx”格式檔案!"});
});
});
function page(n,s){
$("#pageNo").val(n);
$("#pageSize").val(s);
$("#searchForm").submit();
return false;
}
</script>
</head>
<body>
<div id="importBox" class="hide">
<form id="importForm" action="${ctx}/orderexcel/orderexcel/import" method="post" enctype="multipart/form-data"
class="form-search" style="padding-left:20px;text-align:center;" onsubmit="loading('正在匯入,請稍等...');"><br/>
<input id="uploadFile" name="file" type="file" style="width:330px"/><br/><br/>
<input id="btnImportSubmit" class="btn btn-primary" type="submit" value=" 導 入 "/>
</form>
</div>
<ul class="nav nav-tabs">
<li class="active"><a href="${ctx}/orderexcel/orderexcel/">銷售訂單列表</a></li>
</ul>
<form:form id="searchForm" modelAttribute="orderexcel" action="${ctx}/orderexcel/orderexcel/" method="post" class="breadcrumb form-search">
<input id="pageNo" name="pageNo" type="hidden" value="${page.pageNo}"/>
<input id="pageSize" name="pageSize" type="hidden" value="${page.pageSize}"/>
<ul class="ul-form">
<li>
<input id="btnImport" class="btn btn-primary" type="button" value="匯入"/>
<input id="btnExport" class="btn btn-primary" type="button" value="匯出"/>
</li>
<li class="clearfix"></li>
</ul>
</form:form>
<sys:message content="${message}"/>
<table id="contentTable" class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>日期</th>
<th>單據編號</th>
<th>國際單號</th>
<th>國內單號</th>
<th>內部單號</th>
<th>客戶單號</th>
<th>備註</th>
<th>產品型號</th>
<th>庫存編碼</th>
<th>數量</th>
<th>含稅單價</th>
<th>金額</th>
<th>幣種</th>
<th>匯率</th>
<th>地址</th>
<th>國家</th>
<th>插頭</th>
<th>國際貨代</th>
<th>國內貨代</th>
<th>業務員編碼</th>
<th>業務員</th>
<th>往來單位編碼</th>
<th>往來單位</th>
<th>部門編碼</th>
<th>倉庫編碼</th>
<!-- <th>建立時間</th> -->
<%-- <shiro:hasPermission name="orderexcel:orderexcel:edit"><th>操作</th></shiro:hasPermission> --%>
</tr>
</thead>
<tbody>
<c:forEach items="${page.list}" var="orderexcel">
<tr>
<td>
${orderexcel.date}
</td>
<td>
${orderexcel.ordernumber}
</td>
<td>
${orderexcel.internumber}
</td>
<td>
${orderexcel.countrynumber}
</td>
<td>
${orderexcel.number}
</td>
<td>
${orderexcel.customernumber}
</td>
<td>
${orderexcel.remarks}
</td>
<td>
${orderexcel.productnumber}
</td>
<td>
${orderexcel.sku}
</td>
<td>
${orderexcel.number}
</td>
<td>
${orderexcel.taxprice}
</td>
<td>
${orderexcel.totalprice}
</td>
<td>
${orderexcel.currency}
</td>
<td>
${orderexcel.exchangerate}
</td>
<td>
${orderexcel.address}
</td>
<td>
${orderexcel.country}
</td>
<td>
${orderexcel.plug}
</td>
<td>
${orderexcel.interfreightforwarder}
</td>
<td>
${orderexcel.countryfreightforwarder}
</td>
<td>
${orderexcel.salesmannumber}
</td>
<td>
${orderexcel.salesman}
</td>
<td>
${orderexcel.intercoursenumber}
</td>
<td>
${orderexcel.intercourse}
</td>
<td>
${orderexcel.officenumber}
</td>
<td>
${orderexcel.warehousenumber}
</td>
</tr>
</c:forEach>
</tbody>
</table>
<div class="pagination">${page}</div>
</body>
</html>