以前使用poi導出excel,每次都是使用API去一步步畫出excel的樣式,這種方法在遇到複雜的excel需求時,會浪費不少時間。後來決定嘗試使用模板的方法進行導出,這樣只須要關心要導出的數據便可,節省了不少時間。下面的代碼封裝了一些簡單的API,包含了03和07格式的導出, 能知足基本需求,貼出來跟你們分享下,有興趣的同窗也能夠在此基礎上擴展,和你們共享。java
代碼已經分享到git@osc上啦,地址:http://git.oschina.net/carpo/carpo/tree/master/carpo.xlsgit
使用方法apache
poi-3.8-beta4-20110826.jar瀏覽器
poi-ooxml-3.8-beta4.jarxss
poi-ooxml-schemas-3.8-beta4.jaride
xmlbeans-2.6.0.jar函數
1.ExcelExp爲抽象基類,定義了基本操做方法測試
package com.example; import java.io.IOException; import java.util.Map; import javax.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; /** * * excel模板導出基類 * @since jdk1.6 * @date 2016-6-2 * */ public abstract class ExcelExp { protected XSSFWorkbook xssWb; protected XSSFSheet xssSheet; protected HSSFWorkbook hssWb; protected HSSFSheet hssSheet; /** * 設置頁腳 */ public abstract void createFooter(); /** * * 插入行 * @param startRow * @param rows */ public abstract void insertRows(int startRow, int rows); /** * * 替換模板中變量 * @param map */ public abstract void replaceExcelData(Map<String, String> map); /** * 下載excel * @param response * @param filaName * @throws IOException */ public abstract void downloadExcel(HttpServletResponse response, String filaName) throws IOException; public XSSFWorkbook getXssWb() { return xssWb; } public void setXssWb(XSSFWorkbook xssWb) { this.xssWb = xssWb; } public XSSFSheet getXssSheet() { return xssSheet; } public void setXssSheet(XSSFSheet xssSheet) { this.xssSheet = xssSheet; } public HSSFWorkbook getHssWb() { return hssWb; } public void setHssWb(HSSFWorkbook hssWb) { this.hssWb = hssWb; } public HSSFSheet getHssSheet() { return hssSheet; } public void setHssSheet(HSSFSheet hssSheet) { this.hssSheet = hssSheet; } }
2.XssExcelExp爲07格式(.xlsx)的實現類this
package com.example; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLEncoder; import java.util.Map; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFFooter; import org.apache.poi.ss.usermodel.Footer; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; /** * * excel導出類 * <p>處理.xlsx格式<p> * @since jdk1.6 * @date 2016-6-2 * */ public class XssExcelExp extends ExcelExp{ public XssExcelExp() { super(); } /** * 構造函數 * ExcelExp * @param filePath 文件路徑,如com/test/template/test.xlsx * @param sheetNum 要操做的頁籤,0爲第一個頁籤 * @throws IOException */ public XssExcelExp(String filePath, int sheetNum) throws IOException { URL resource = this.getClass().getClassLoader().getResource(filePath); InputStream is = new FileInputStream(resource.getFile()); xssWb = new XSSFWorkbook(is); xssSheet = xssWb.getSheetAt(sheetNum); } /** * 設置頁腳 */ public void createFooter(){ Footer footer = xssSheet.getFooter(); footer.setRight("第" + HSSFFooter.page() + "頁,共" + HSSFFooter.numPages() + "頁"); } /** * * 插入行 * @param startRow * @param rows */ public void insertRows(int startRow, int rows){ int bottomRow = xssSheet.getLastRowNum(); if(startRow > bottomRow){ int n = startRow - bottomRow; for(int i = 1; i <= n; i++){ xssSheet.createRow(bottomRow + i); } } xssSheet.shiftRows(startRow, xssSheet.getLastRowNum(), rows, true, false); } /** * * 替換模板中變量 * @param map */ public void replaceExcelData(Map<String, String> map){ int rowNum = xssSheet.getLastRowNum(); for(int i = 0;i <= rowNum; i++){ XSSFRow row = xssSheet.getRow(i); if(row == null) continue; for(int j = 0;j < row.getPhysicalNumberOfCells();j++){ XSSFCell cell = row.getCell(j); if(cell == null) continue; String key = cell.getStringCellValue(); if(map.containsKey(key)){ cell.setCellValue(map.get(key)); } } } } /** * 下載excel * @param response * @param filaName * @throws IOException */ public void downloadExcel(HttpServletResponse response, String filaName) throws IOException{ String encodeFileName = URLEncoder.encode(filaName,"UTF-8"); response.addHeader("Content-Disposition","attachment;filename=" +encodeFileName); ServletOutputStream out = response.getOutputStream(); xssWb.write(out); out.flush(); out.close(); } }
3.HssExcelExp爲03格式(.xls)的實現類spa
package com.example; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLEncoder; import java.util.Map; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFFooter; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Footer; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFWorkbook; /** * * excel導出類 * <p>處理.xls格式<p> * @since jdk1.6 * @date 2016-6-2 * */ public class HssExcelExp extends ExcelExp{ public HssExcelExp() { super(); } /** * 構造函數 * ExcelExp * @param filePath 文件路徑,如com/test/template/test.xls * @param sheetNum 要操做的頁籤,0爲第一個頁籤 * @throws IOException */ public HssExcelExp(String filePath, int sheetNum) throws IOException { URL resource = this.getClass().getClassLoader().getResource(filePath); InputStream is = new FileInputStream(resource.getFile()); hssWb = new HSSFWorkbook(is); hssSheet = hssWb.getSheetAt(sheetNum); } @Override public void createFooter() { Footer footer = hssSheet.getFooter(); footer.setRight("第" + HSSFFooter.page() + "頁,共" + HSSFFooter.numPages() + "頁"); } @Override public void downloadExcel(HttpServletResponse response, String filaName) throws IOException { String encodeFileName = URLEncoder.encode(filaName,"UTF-8"); response.addHeader("Content-Disposition","attachment;filename=" +encodeFileName); ServletOutputStream out = response.getOutputStream(); hssWb.write(out); out.flush(); out.close(); } @Override public void insertRows(int startRow, int rows) { int bottomRow = hssSheet.getLastRowNum(); if(startRow > bottomRow){ int n = startRow - bottomRow; for(int i = 1; i <= n; i++){ hssSheet.createRow(bottomRow + i); } } hssSheet.shiftRows(startRow, hssSheet.getLastRowNum(), rows, true, false); } @Override public void replaceExcelData(Map<String, String> map) { int rowNum = hssSheet.getLastRowNum(); for(int i = 0;i <= rowNum; i++){ HSSFRow row = hssSheet.getRow(i); if(row == null) continue; for(int j = 0;j < row.getPhysicalNumberOfCells();j++){ HSSFCell cell = row.getCell(j); if(cell == null) continue; String key = cell.getStringCellValue(); if(map.containsKey(key)){ cell.setCellValue(map.get(key)); } } } } }
基於不一樣的excel格式去實例化不一樣的實現類便可,調用指定的API可實現相應的功能,例如 添加頁腳、插入行、爲excel中的變量賦值等。如下面excel格式爲例,裏面存在變量xlsx_a、xlsx_b、
xlsx_c,要爲變量賦值。在第三行要插入行,而後寫入數據。
public static void main(String[] args) throws Exception { //傳遞模板地址和要操做的頁籤 ExcelExp excel = new XssExcelExp("com/example/template/test.xlsx", 0); //建立頁腳,打印excel時顯示頁數 excel.createFooter(); //插入行 int startRow = 2;//起始行 int rows = 5;//插入行數 excel.insertRows(startRow, rows); //在插入的行中寫入數據 wirteXssExcel(excel); //爲模板中變量賦值 Map<String, String> map = new HashMap<String, String>(); map.put("xlsx_a", "2016-06-07 12:00:00"); map.put("xlsx_b", "測試"); map.put("xlsx_c", "12345"); excel.replaceExcelData(map); //導出,此處只封裝了瀏覽器下載方式 //調用downloadExcel,返回輸出流給客戶端 String fileName = "export1.xlsx"; excel.downloadExcel(response, fileName); } public void wirteXssExcel(ExcelExp excel){ XSSFSheet sheet = excel.getXssSheet(); List list = new ArrayList(); for (int i = 0; i < list.size(); i++) { XSSFRow row = sheet.createRow(i+3); row.createCell(0).setCellValue(String.valueOf(i + 1)); row.createCell(1).setCellValue("111"); row.createCell(2).setCellValue("222"); row.createCell(3).setCellValue("333"); } } public void wirteHssExcel(ExcelExp excel){ HSSFSheet sheet = excel.getHssSheet(); List list = new ArrayList(); for (int i = 0; i < list.size(); i++) { HSSFRow row = sheet.createRow(i+3); row.createCell(0).setCellValue(String.valueOf(i + 1)); row.createCell(1).setCellValue("111"); row.createCell(2).setCellValue("222"); row.createCell(3).setCellValue("333"); } }
勘誤
1.在使用中發現,插入行方法,在模板最後插入行時會報錯( java.lang.IllegalArgumentException: firstMovedIndex, lastMovedIndex out of order ),現已修復,文中代碼已更新。