做oa系統的都會有這個要求:根據數據導入excel文件。只需要點擊一下,你所需要的數據就直接生成一個excel文件了,是不是很方便?
是的沒錯,很方便,但是對於我們來說是一件很痛苦的事情,所以說一下我的經歷。因為是第一次寫excel文件導出,所以代碼可能寫的很爛,不喜勿噴。
有什么意見也可以直接留言哦,希望與大家一起交流
第一步,先在pom.xml文件依賴jar包:
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.6</version> </dependency>
第二部,我們開始寫工具類了:
第一個工具類創建excel表單內容:
public class CreateExcelUtil{ /** * 導出Excel * @param sheetName sheet名稱 * @param title 標題 * @param values 內容 * @param wb HSSFWorkbook對象 * @return */ public static HSSFWorkbook getHSSFWorkbook(String sheetName, String []title, String [][]values, HSSFWorkbook wb){ // 第一步,創建一個HSSFWorkbook,對應一個Excel文件 if(wb == null){ wb = new HSSFWorkbook(); } // 第二步,在workbook中添加一個sheet,對應Excel文件中的sheet HSSFSheet sheet = wb.createSheet(sheetName); //默認寬度 sheet.setDefaultColumnWidth(25); //默認高度 sheet.setDefaultRowHeightInPoints(20); // 第三步,在sheet中添加表頭第0行,注意老版本poi對Excel的行數列數有限制 HSSFRow row = sheet.createRow(0); sheet.autoSizeColumn(1,true);//寬度自適應 // 第四步,創建單元格,並設置值表頭 設置表頭居中 HSSFCellStyle style = wb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 創建一個居中格式 //聲明列對象 HSSFCell cell = null; //創建標題 for(int i=0;i<title.length;i++){ cell = row.createCell(i); cell.setCellValue(title[i]); cell.setCellStyle(style); } //創建內容 for(int i=0;i<values.length;i++){ row = sheet.createRow(i + 1); for(int j=0;j<values[i].length;j++){ //將內容按順序賦給對應的列對象 row.createCell(j).setCellValue(values[i][j]); } } return wb; } }
第二個工具類:通過流的方式響應回客戶端
public class ExcelPortUtil{ //發送響應流方法 public static void setResponseHeader(HttpServletResponse response, String fileName,String[]title,String[][]content) { try { //創建HSSFWorkbook HSSFWorkbook wb = CreateExcelUtil.getHSSFWorkbook(fileName, title, content, null); try { fileName = new String(fileName.getBytes(),"ISO8859-1"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } response.setContentType("application/octet-stream;charset=ISO8859-1"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls"); response.addHeader("Param", "no-cache"); response.addHeader("Cache-Control", "no-cache"); OutputStream os = response.getOutputStream(); wb.write(os); os.flush(); os.close(); } catch (Exception ex) { ex.printStackTrace(); } } //根據參數返回一個二維數組 public static String[][] getContent(int length){ return new String[length][]; } //獲取properties文件並解決中文亂碼問題 public static Properties getProperties() throws IOException { Properties prop = new Properties(); prop.load(new InputStreamReader(Client.class.getClassLoader().getResourceAsStream("reportForm.properties"), "UTF-8")); return prop; } // public static void main(String[] args) throws IOException { // Properties pro = ExcelPortUtil.getProperties(); // System.out.println(pro.getProperty("whMaterialClass.typeName")); // } }
因為excel表單行頭是可以變化的,所以我們應該寫一個property文件,這樣我們維護起來也方便
#excel文件信息 ex.excelFileName = 數據信息表 #物質類型管理信息 whMaterialClass.fileName = 物質分類信息表 whMaterialClass.typeName = 物質類型名稱 whMaterialClass.state = 物質類型代碼 whMaterialClass.remark = 物質類型備注
然后我們需要在業務層麻煩一點:
/** * 生成excel文件 * @param param * @param response * @throws IOException */ public void excelPort(WhMaterialClassParam param, HttpServletResponse response) throws IOException { Properties pro = ExcelPortUtil.getProperties(); //獲取數據 List<WhMaterialClass> list = whMaterialClassMapper.getAllBySeach(param); //excel標題 String[] title = { pro.getProperty("whMaterialClass.typeName"), pro.getProperty("whMaterialClass.state"), pro.getProperty("whMaterialClass.remark") }; //數據 String[][] content = ExcelPortUtil.getContent(list.size()); for (int i = 0; i < list.size(); i++) { WhMaterialClass wms = list.get(i); content[i] = new String[title.length]; content[i][0] = wms.getMaterialClassName(); content[i][1] = wms.getMaterialClassCode(); content[i][2] = wms.getRemark(); } ExcelPortUtil.setResponseHeader(response,pro.getProperty("whMaterialClass.fileName"),title,content); }