業務:動態生成模板導出Excel,用戶修改完再導入Excel.
Spring boot + bootstrap + poi
1.添加Dependence
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency>
前者用於引入HSSFWorkbook;后者用於引入XSSFWorkbook.
2.生成模板並導出Excel
//生成模板 function modleCreate(){ //清空數據 var oaId= $("#adjOAId").val(); var adjOrg= $("#adjOrg").val(); var adjDepart=$("#adjDepart").val(); var adjSubject=$("#adjSubject").val(); window.location.href="budgetOaController/exportTemplate?adjOrg="+ adjOrg +"&&adjDepart=" +adjDepart +"&&adjSubject="+adjSubject+"&&oaId="+oaId; }
@RequestMapping(value="/exportTemplate",method=RequestMethod.GET) public void exportTemplate(HttpServletResponse response,@RequestParam String adjOrg,@RequestParam String adjSubject, @RequestParam String adjDepart,@RequestParam String oaId) throws IOException{ // 聲明一個工作薄 HSSFWorkbook workbook = new HSSFWorkbook(); //創建一個Excel表單,參數為sheet的名字 HSSFSheet sheet = workbook.createSheet("模板表"); //創建表頭 setTitle(workbook, sheet); List<Map<String, Object>> oalist = budgetAdjustService.getOainform(oaId); //新增數據行,並且設置單元格數據 HSSFRow hssfRow = sheet.createRow(1); for(Map map :oalist) { hssfRow.createCell(0).setCellValue(map.get("adjustType")+""); hssfRow.createCell(1).setCellValue(map.get("applyDate")+""); hssfRow.createCell(2).setCellValue(map.get("processCode")+""); hssfRow.createCell(3).setCellValue(map.get("applyOrganization")+""); hssfRow.createCell(4).setCellValue(map.get("applyDepartment")+""); hssfRow.createCell(5).setCellValue(map.get("flag")+""); } hssfRow.createCell(6).setCellValue(adjOrg); hssfRow.createCell(7).setCellValue(adjDepart); hssfRow.createCell(8).setCellValue(adjSubject); /*hssfRow.createCell(1).setCellValue(budgetadjust.getApplyDate()); hssfRow.createCell(2).setCellValue(budgetadjust.getProcessCode()); hssfRow.createCell(3).setCellValue(budgetadjust.getApplyOrganization()); hssfRow.createCell(4).setCellValue(budgetadjust.getApplyDepartment()); hssfRow.createCell(5).setCellValue(budgetadjust.getFlag()); hssfRow.createCell(6).setCellValue(budgetadjust.getExportorganization()); hssfRow.createCell(7).setCellValue(budgetadjust.getExportdepartment()); hssfRow.createCell(8).setCellValue(budgetadjust.getExportsubject()); }*/ // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); String fileName = "Template -" + new Date().getTime() + ".xls"; //清空response response.reset(); //設置response的Header response.addHeader("Content-Disposition", "attachment;filename="+ fileName); OutputStream os = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/vnd.ms-excel;charset=gb2312"); //將excel寫入到輸出流中 workbook.write(os); os.flush(); os.close(); } // 創建表頭 private void setTitle(HSSFWorkbook workbook, HSSFSheet sheet) { HSSFRow row = sheet.createRow(0); // 設置列寬,setColumnWidth的第二個參數要乘以256,這個參數的單位是1/256個字符寬度 sheet.setColumnWidth(8, 60 * 256); // 設置為居中加粗 HSSFCellStyle style = workbook.createCellStyle(); HSSFFont font = workbook.createFont(); font.setBold(true); style.setFont(font); //導出的Excel頭部 String[] headers = { "調整類型", "申請日期", "OA流程編號", "申請組織", "申請部門", "是否涉及人力成本", "調出組織", "調出部門", "調出科目", "調出月份", "調出金額", "查詢費控系統", "調入組織", "調入部門", "調入科目", "調入月份", "調入金額", "調整原因" }; // 設置表格默認列寬度為15個字節 sheet.setDefaultColumnWidth((short) 16); for (short i = 0; i < headers.length; i++) { HSSFCell cell = row.createCell(i); HSSFRichTextString text = new HSSFRichTextString(headers[i]); cell.setCellValue(text); cell.setCellStyle(style); } }
2.1 導出結果
3.導入Excel
<div class="row"> <div class="col-md-12"> <section class="panel"> <header class="panel-heading"> OA預算調整模板導入 </header> <div class="modal-body"> <div class="row"> <div class="col-lg-12"> <form id="defaultForm" method="" class="form-horizontal recoveryNodeForm" action=""> <div class="col-lg-12"> <div class="form-group"> <label class="col-lg-3 control-label">導入文件</label> <div class="col-lg-6"> <input type="file" class="form-control" style="height:36px;" name="uploadFile" id="uploadFile"/> </div> <button type="button" class="btn btn-primary" id="uploadExcel">上傳</button> </div> </div> <input type="hidden" name="pkId" value="" /> </form> </div> </div> <div> <span><b>導入結果反饋</b></span> <ul id="exportResult"> </ul> </div> </div> </section> </div> </div> <!-- 工具JS由開發人員編寫 --> <script th:inline="javascript"> /*<![CDATA[*/ $(function(){ $(".recoveryNodeForm").bootstrapValidator({ message: 'This value is not valid', live: 'submitted', fields: {/*驗證*/ uploadFile: { message: '導入文件無效', validators: { notEmpty: {/*非空提示*/ message: '導入文件不能為空' }, regexp: { regexp: /\.xl(s[xmb]|t[xm]|am|s)$/, //regexp: /.xls$/, // extension: 'zip,rar,doc,docx,pdf', message: '導入文件類型必須是excel' } /* uploadFile: { extension: 'zip,rar,doc,docx,pdf', // type:'zip,rar,doc,docx,pdf', maxSize: 1024*100, minSize: 1024, message: '僅支持大小在1M~5M之間,類型是zip,rar,doc,docx,pdf文件!' } */ } } } }) }); $("#uploadExcel").on("click","",function () { $(".recoveryNodeForm").data("bootstrapValidator").validate(); var flag = $(".recoveryNodeForm").data("bootstrapValidator").isValid(); alert(flag+"===========flag==========="); if(!flag){ //未通過驗證 return false; } var fileObj = document.getElementById("uploadFile").files[0]; var formFile = new FormData(); formFile.append("file", fileObj); var data = formFile; $.ajax({ url: "budgetOaController/upload", data: data, type: "Post", dataType: "json", cache: false,//上傳文件無需緩存 processData: false,//用於對data參數進行序列化處理 這里必須false contentType: false, //必須 success: function (result) { console.log(JSON.stringify(result)) var htmlstr = ''; if(result.ajaxResultJson.success==false){ htmlstr = '<li>上傳失敗</li>'; } else { htmlstr = '<li>上傳成功</li>'; } $('#exportResult').html(htmlstr); }, error: function(XMLHttpRequest, textStatus, errorThrown){ layer.msg("系統錯誤",{icon: 2}); } }); }); /*]]>*/ </script>
// 導入Excel
@RequestMapping(value = "upload", method = RequestMethod.POST)
public AjaxResultJson upload(MultipartFile file) {
AjaxResultJson result = new AjaxResultJson();
if (file == null) {
result.setMsg("file不能為空");
result.setObj("Excel導入失敗");
return result;
}
List<Budgetadjust> list = new ArrayList<>();
String fileName = file.getOriginalFilename(); //獲取文件名
try {
//解決You need to call a different part of POI to process this data (eg XSSF instead of HSSF)問題
// Workbook workbook=WorkbookFactory.create(file.getInputStream());
HSSFWorkbook workbook = new HSSFWorkbook(new POIFSFileSystem(file.getInputStream()));
// 有多少個sheet
int sheets = workbook.getNumberOfSheets();
for (int i = 0; i < sheets; i++) {
HSSFSheet sheet = workbook.getSheetAt(i);
// 獲取多少行
int rows = sheet.getPhysicalNumberOfRows();
Budgetadjust budgetadjust = null;
// 遍歷每一行,注意:第 0 行為標題
for (int j = 1; j < rows; j++) {
budgetadjust = new Budgetadjust();
// 獲得第 j 行
HSSFRow row = sheet.getRow(j);
budgetadjust.setAdjustType(row.getCell(0).toString());// 調整類型
budgetadjust.setApplyDate(row.getCell(1).toString());// 申請日期
budgetadjust.setProcessCode(row.getCell(2).toString());// OA流程編號
budgetadjust.setApplyOrganization(row.getCell(3).toString());// 申請組織
budgetadjust.setApplyDepartment(row.getCell(4).toString());// 申請部門
budgetadjust.setFlag(row.getCell(5).toString());// 是否涉及人力成本
budgetadjust.setExportorganization(row.getCell(6).toString());// 調出組織
budgetadjust.setExportdepartment(row.getCell(7).toString());// 調出部門
budgetadjust.setExportsubject(row.getCell(8).toString());// 調出科目
budgetadjust.setExportmonth(row.getCell(9).toString());// 調出月份
budgetadjust.setExportmoney(row.getCell(10).toString());// 調出金額
budgetadjust.setCostControl(row.getCell(11).toString());// 查詢費控系統
budgetadjust.setImportorganization(row.getCell(12).toString());// 調入組織
budgetadjust.setImportdepartment(row.getCell(13).toString());// 調入部門
budgetadjust.setImportsubject(row.getCell(14).toString());// 調入科目
budgetadjust.setImportmonth(row.getCell(15).toString());// 調入月份
budgetadjust.setImportmoney(row.getCell(16).toString());// 調入金額
budgetadjust.setAdjustreason(row.getCell(17).toString());// 調整原因
list.add(budgetadjust);
}
}
budgetAdjustService.saveOABudget(list);
} catch (IOException e) {
result.setSuccess(false);
result.setMsg(e.getMessage());
}
result.setSuccess(true);
result.setMsg("保存成功"); // 可以傳文件名給頁面 String fileName = file.getOriginalFilename(); //獲取文件名
result.setObj(list);
return result;
}
注意:
1.要想讓<input type="file">
標簽 能夠上傳多個文件,只需要在<input type="file">
里添加 multiple
或 multiple="multiple"
屬性。
2. Execl 導出鎖定列和隱藏單元的值
1.Execl列的鎖定 HSSFCellStyle style = workbook.createCellStyle(); style.setLocked(true);//設置列的鎖定狀態為鎖定
2.隱藏單元格的值 hssfRow.createCell(9).setCellValue("12月"); // 調出月
hssfRow.createCell(20).setCellValue("A1"); // 調出期間A1
sheet.setColumnHidden((short)20, true); //隱藏第單元格20的值A1
3.設置表頭字體樣式背景顏色
private void setTitle(HSSFWorkbook workbook, HSSFSheet sheet) { HSSFRow row = sheet.createRow(0); // 設置列寬,setColumnWidth的第二個參數要乘以256,這個參數的單位是1/256個字符寬度 sheet.setColumnWidth(8, 60 * 256); // 設置為居中加粗 HSSFCellStyle style = workbook.createCellStyle(); HSSFCellStyle style2 = workbook.createCellStyle(); style.setLocked(true);//設置列的鎖定狀態 style2.setLocked(true); HSSFFont font = workbook.createFont(); HSSFFont font2 = workbook.createFont(); font.setBold(true);//設置字體鎖定狀態 style.setFont(font); style.setAlignment(HorizontalAlignment.CENTER);//水平居中 style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中 // 導出的Excel頭部 String[] headers = { "調整類型", "申請日期", "OA流程編號", "申請組織", "申請部門", "是否涉及人力成本", "調出組織", "調出部門", "調出科目", "調出月份", "調出金額", "查詢費控系統", "調入組織", "調入部門", "調入科目", "調入月份", "調入金額", "調整原因" }; // 設置表格默認列寬度為15個字節 sheet.setDefaultColumnWidth((short) 16); for (short i = 0; i < headers.length; i++) { HSSFCell cell = row.createCell(i); HSSFRichTextString text = new HSSFRichTextString(headers[i]); cell.setCellValue(text); if(i==10 || i>11) { font2.setBold(true); font2.setColor(HSSFColor.RED.index); //顏色 style2.setFont(font2); style2.setAlignment(HorizontalAlignment.CENTER);//水平居中 style2.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中 style2.setFillPattern(FillPatternType.SOLID_FOREGROUND); style2.setFillForegroundColor(IndexedColors.YELLOW.index); row.getCell(i).setCellStyle(style2); }else { cell.setCellStyle(style); } } }
效果圖:
----------------------------------------------------
相關鏈接:https://blog.csdn.net/daihuimaozideren/article/details/78777656
https://www.cnblogs.com/zhuwenxia/p/9443742.html
文件上傳鏈接: https://blog.csdn.net/chenxueshanBlog/article/details/78894838
POI 3.17版本生成excel的一些樣式設置:
https://blog.csdn.net/m0_37353769/article/details/81872152
https://blog.csdn.net/phil_jing/article/details/78307819
獲取單元格類型getCellType
POI:https://blog.csdn.net/huasxiaopeng/article/details/42641809
https://blog.csdn.net/jiankang66/article/details/89040742
注意POI4.0.0版本區別