我本身的jar包下載html
1、介紹
經常有客戶這樣子要求:你要把咱們的報表直接用Excel打開(電信系統、銀行系統)。或者是:咱們已經習慣用Excel打印。這樣在咱們實際的開發中,不少時候須要實現導入、導出Excel的應用。
目前,比較經常使用的實現Java導入、導出Excel的技術有:Jakarta POI、freemarker和Java Excel
下面我就分別講解一下如何使用這些技術實現導入、導出Excel
2、使用Jakarta POI導出Excel
Jakarta POI 是一套用於訪問微軟格式文檔的Java API。Jakarta POI有不少組件組成,其中有用於操做Excel格式文件的HSSF和用於操做Word的HWPF,
在各類組件中目前只有用於操做Excel的HSSF相對成熟。官方主頁http://poi.apache.org/index.html,API文檔http://poi.apache.org/apidocs/index.html
1.環境配置java
下載jar
官方下載:http://poi.apache.org/download.html這裏能夠下載到它的最新版本和文檔,目前最新版本是3.7,這裏使用比較穩定的3.6版。
加入jar包
將根目錄下的poi-3.6-20091214.jar和Lib目錄下三個通用包 commons-logging-1.1.jar junit-3.8.1.jar log4j-1.2.13.jar拷貝到項目的Lib下
2.Jakarta POI HSSF API組件sql
HSSF(用於操做Excel的組件)提供給用戶使用的對象在rg.apache.poi.hssf.usermodel包中,主要部分包括Excel對象,樣式和格式,還有輔助操做。有如下幾種對象:
經常使用組件:
HSSFWorkbook excel的文檔對象
HSSFSheet excel的表單
HSSFRow excel的行
HSSFCell excel的格子單元
HSSFFont excel字體
HSSFDataFormat 日期格式
HSSFHeader sheet頭
HSSFFooter sheet尾(只有打印的時候才能看到效果)
樣式:
HSSFCellStyle cell樣式
輔助操做包括:
HSSFDateUtil 日期
HSSFPrintSetup 打印
HSSFErrorConstants 錯誤信息表
3. 基本操做步驟apache
首先,理解一下一個Excel的文件的組織形式,一個Excel文件對應於一個workbook(HSSFWorkbook),一個workbook能夠有多個sheet(HSSFSheet)組成,一個sheet是由多個row(HSSFRow)組成,一個row是由多個cell(HSSFCell)組成。
基本操做步驟:
a、用HSSFWorkbook打開或者建立「Excel文件對象」
b、用HSSFWorkbook對象返回或者建立Sheet對象
c、用Sheet對象返回行對象,用行對象獲得Cell對象
d、對Cell對象讀寫。api
4.我本身寫的測試用例數組
import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.Region; public class POIExportExcel { public HSSFWorkbook generateExcel1(List list, HSSFWorkbook wb, String title) { //行的數量 int rows = 0; HSSFSheet sheet = wb.createSheet("Sheet1"); // 數據格樣式 HSSFCellStyle dataCellStyle = createDataCellStyle(wb); // 小標題樣式 HSSFCellStyle cellStyle = createCellStyle(wb); sheet.setDefaultRowHeight((short) 400);//設置全部行高爲400 //設置列寬 sheet.setColumnWidth((short) 1, (short) 2800); sheet.setColumnWidth((short) 2, (short) 2800); sheet.setColumnWidth((short) 3, (short) 2800); sheet.setColumnWidth((short) 4, (short) 2800); sheet.setColumnWidth((short) 5, (short) 2800); sheet.setColumnWidth((short) 6, (short) 2800); sheet.setColumnWidth((short) 7, (short) 2800); sheet.setColumnWidth((short) 8, (short) 2800); sheet.setColumnWidth((short) 9, (short) 2800); sheet.setColumnWidth((short) 10, (short) 3200); sheet.setColumnWidth((short) 11, (short) 3200); sheet.setColumnWidth((short) 12, (short) 3200); sheet.setColumnWidth((short) 13, (short) 3200); //標題行 HSSFRow row1 = sheet.createRow((short) (rows++)); row1.setHeight((short) 500); sheet.addMergedRegion(new Region(0, (short) 0, 0, (short) 13));//橫跨1-14列 createCell(row1, (short) 0, cellStyle, title); //表頭行(1,2列合併;3,4,5,6,7列合併;8,9列合併) HSSFRow row2 = sheet.createRow((short) (rows++)); sheet.addMergedRegion(new Region(1, (short) 0, 1, (short) 1)); sheet.addMergedRegion(new Region(1, (short) 2, 1, (short) 6)); sheet.addMergedRegion(new Region(1, (short) 7, 1, (short) 8)); sheet.addMergedRegion(new Region(1, (short) 9, 1, (short) 9)); sheet.addMergedRegion(new Region(1, (short) 10, 1, (short) 10)); sheet.addMergedRegion(new Region(1, (short) 11, 1, (short) 11)); sheet.addMergedRegion(new Region(1, (short) 12, 1, (short) 12)); sheet.addMergedRegion(new Region(1, (short) 13, 1, (short) 13)); createCell(row2, (short) 0, dataCellStyle, "name1"); createNullCell(row2, (short) 1, dataCellStyle); createCell(row2, (short) 2, dataCellStyle, "name2"); createNullCell(row2, (short) 3, dataCellStyle); createNullCell(row2, (short) 4, dataCellStyle); createNullCell(row2, (short) 5, dataCellStyle); createNullCell(row2, (short) 6, dataCellStyle); createCell(row2, (short) 7, dataCellStyle, "name3"); createNullCell(row2, (short) 8, dataCellStyle); createCell(row2, (short) 9, dataCellStyle, "name4"); createCell(row2, (short) 10, dataCellStyle, "name5"); createCell(row2, (short) 11, dataCellStyle, "name6"); createCell(row2, (short) 12, dataCellStyle, "name7"); createCell(row2, (short) 13, dataCellStyle, "name8"); //遍歷集合,保存數據到單元格 for(int i=0;i<list.size();i++){ Object javaBean = list.get(i); //具體的數據值經過對象去獲取,這裏簡單給值 String variable1 = "value1"+"_"+i; String variable2 = "value2"+"_"+i; String variable3 = "value3"+"_"+i; String variable4 = "value4"+"_"+i; String variable5 = "value5"+"_"+i; String variable6 = "value6"+"_"+i; String variable7 = "value7"+"_"+i; String variable8 = "value8"+"_"+i; HSSFRow rowi = sheet.createRow((short) (rows++)); sheet.addMergedRegion(new Region(i+2, (short) 0, i+2, (short) 1)); sheet.addMergedRegion(new Region(i+2, (short) 2, i+2, (short) 6)); sheet.addMergedRegion(new Region(i+2, (short) 7, i+2, (short) 8)); sheet.addMergedRegion(new Region(i+2, (short) 9, i+2, (short) 9)); sheet.addMergedRegion(new Region(i+2, (short) 10, i+2, (short) 10)); sheet.addMergedRegion(new Region(i+2, (short) 11, i+2, (short) 11)); sheet.addMergedRegion(new Region(i+2, (short) 12, i+2, (short) 12)); sheet.addMergedRegion(new Region(i+2, (short) 13, i+2, (short) 13)); createCell(rowi, (short) 0, dataCellStyle, variable1); createNullCell(rowi, (short) 1, dataCellStyle); createCell(rowi, (short) 2, dataCellStyle, variable2); createNullCell(rowi, (short) 3, dataCellStyle); createNullCell(rowi, (short) 4, dataCellStyle); createNullCell(rowi, (short) 5, dataCellStyle); createNullCell(rowi, (short) 6, dataCellStyle); createCell(rowi, (short) 7, dataCellStyle, variable3); createNullCell(rowi, (short) 8, dataCellStyle); createCell(rowi, (short) 9, dataCellStyle, variable4); createCell(rowi, (short) 10, dataCellStyle, variable5); createCell(rowi, (short) 11, dataCellStyle, variable6); createCell(rowi, (short) 12, dataCellStyle, variable7); createCell(rowi, (short) 13, dataCellStyle, variable8); } return wb; } /** * 建立單元格 * @param row * @param id * @param style * @param value */ private void createCell(HSSFRow row, short id, HSSFCellStyle style, String value) { HSSFCell cell = row.createCell((short) id); // cell.setEncoding(HSSFCell.ENCODING_UTF_16); cell.setCellValue(value); cell.setCellStyle(style); } /** * 建立空的單元格 */ private HSSFCell createNullCell(HSSFRow row, short id, HSSFCellStyle style) { HSSFCell null1Cell = row.createCell(id); null1Cell.setCellStyle(style); return null1Cell; } /** * 設置數據單元格樣式 * @param wb * @return */ private HSSFCellStyle createDataCellStyle(HSSFWorkbook wb) { HSSFCellStyle dataCellStyle = wb.createCellStyle(); // 水平居中 dataCellStyle.setAlignment(HSSFCellStyle.ALIGN_LEFT); dataCellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); dataCellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); dataCellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); dataCellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); return dataCellStyle; } /** * 設置單元格樣式 * @param wb * @return */ private HSSFCellStyle createCellStyle(HSSFWorkbook wb) { // 小標題樣式 HSSFCellStyle cellStyle = wb.createCellStyle(); // 水平居中 cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 字體 HSSFFont littleFont = wb.createFont(); // 設置字體爲粗體 littleFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 而後將字體關聯到樣式 cellStyle.setFont(littleFont); cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); return cellStyle; } public static void main(String[] args){ /*String serverPath = request.getSession().getServletContext().getRealPath("/")+"exportExcel"; //在服務器端建立文件夾 File file = new File(serverPath+path); if(!file.exists()){ file.mkdir(); } SimpleDateFormat sfm = new SimpleDateFormat("yyyy-MM-dd"); String filename = "excel" + "_" + sfm.format(new java.util.Date()); String encodedfileName = new String(filename.getBytes(), "GBK"); FileOutputStream out = new FileOutputStream(serverPath+path+"/"+encodedfileName+".xls"); */ new POIExportExcel(); String title = "POI導出excel"; List list = new ArrayList<String>(); //加入兩條作個測試 list.add(new String()); list.add(new String()); try { FileOutputStream out = new FileOutputStream("D:/"+title+".xls"); HSSFWorkbook wb =new HSSFWorkbook(); wb = new POIExportExcel().generateExcel1(list,wb,title); wb.write(out); /*List srcfile=new ArrayList(); srcfile.add(new File(serverPath+path+"/"+encodedfileName+".xls")); //將服務器上存放Excel的文件夾打成zip包 File zipfile = new File(serverPath+path+".zip"); ZipUtil.zipFiles(srcfile, zipfile); //彈出下載框供用戶下載 this.downFile(response,serverPath, path+".zip");*/ } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
結果以下圖:服務器
3、使用Jakarta POI讀取(導入)Exceldom
依賴dom4j.jar和xmlbeans.jarxss
沒有的話會拋出:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlObjectide
import java.io.File; import java.io.FileInputStream; import java.sql.Date; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class MyExcelReader { /** * 分析獲取上傳的excel文件中的數據信息。 僅對Excel文件的第一張表進行分析,分析過程當中若是遇到空行就結束。 * @param file * excel * @return excel中對應的數據以二維數組形式返回 * @throws Exception */ private String[][] readExcel(File file) { String[][] data = null; Workbook wb = null; try { // 解析excel2003 if (file.getName().endsWith(".xls")) { POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream( file.getPath())); // excel數據對象 wb = new HSSFWorkbook(fs); } // 解析excel2007及以上 if (file.getName().endsWith(".xlsx")) { wb = new XSSFWorkbook(new FileInputStream(file.getPath())); } // excel中對應的表單 Sheet sheet = wb.getSheetAt(0); // excel中的有效列數 int colNum = getValidColNum(sheet); // 只有excel的有效列數大於零纔對數據進行分析 if (colNum > 0) { // 從Excel中獲取到的有效數據 data = getExcelData(sheet, colNum); } } catch (Exception e) { e.printStackTrace(); } return data; } /** * 獲得表單的有效列數. 獲取表單第一行開始位置連續非空單元格的個數 * * @param sheet * Excel的表單 * @return 列數 * @throws Exception */ private int getValidColNum(Sheet sheet) throws Exception { // 判斷文件是否爲空文件 if (sheet.getRow(0) == null) { System.out.println("文件爲空"); throw new Exception("error.importExcel.blankExcelFile"); } // 表單總列數 int colNum = sheet.getRow(0).getPhysicalNumberOfCells(); Row row = sheet.getRow(0); // 若是表單第一行即表頭位置出現空單元格,該單元格後面的信息不在導入 for (int i = 0; i < colNum; i++) { if (row.getCell((short) i) != null) { Cell cell = row.getCell((short) i); String value = this.getCellValue(cell); if (StringUtils.isEmpty(value)) { colNum = i; break; } } // 若是列表頭信息爲空,不讀取後面的數據 else { colNum = i; } } return colNum; } /** * 讀取Excel數據. 讀取過程當中,遇到空行自動中止,捨棄空行後面的數據。 可根據數組信息獲取Excel的有效行數 * * @param sheet * 表單對象 * @param colNum * 有效列數 * @return 數據二維數組 */ private String[][] getExcelData(Sheet sheet, int colNum) { int tempRowNum = sheet.getPhysicalNumberOfRows(); // 存儲從Excel表中讀取的數據信息 List<List<String>> dataList = new ArrayList<List<String>>(); // 讀取Excel數據,將其存儲在可變長的List容器中,同時獲得Excel文件的有效數據行數 int rowNum = 0; for (; rowNum < tempRowNum && sheet.getRow(rowNum) != null; rowNum++) { List<String> rowData = new ArrayList<String>(); // 對行信息進行累加,判斷該行是否爲空行 String rowValue = ""; for (int j = 0; j < colNum; j++) { if (sheet.getRow(rowNum).getCell((short) j) != null) { Cell cell = sheet.getRow(rowNum).getCell((short) j); String value = getCellValue(cell); rowData.add(value); rowValue += value; } else { rowData.add(null); } } // 讀取信息時如遇到空行,結束讀入 if (rowValue.length() == 0) { break; } else { dataList.add(rowData); } } // 將Excel數據轉存到數組對象中 String[][] data = new String[rowNum][colNum]; for (int i = 0; i < dataList.size(); i++) { for (int j = 0; j < dataList.get(i).size(); j++) { data[i][j] = dataList.get(i).get(j); } } return data; } /** * 獲得Excel單元格的數據內容 * * @param cell * Excel單元格對象 * @return 單元格的內容 */ public String getCellValue(Cell cell) { // excel的日期格式和java的有很大區別 if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC && DateUtil.isCellDateFormatted(cell)) { return new Date(cell.getDateCellValue().getTime()).toString(); } else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) { double value = cell.getNumericCellValue(); return new DecimalFormat("###.####").format(value); } else { String result = ""; try { RichTextString textString = cell.getRichStringCellValue(); if (textString != null) { result = textString.getString().trim(); result = this.subStr(result); if (result.length() > 0) { char firstChar = result.charAt(0); // 若是信息不是以英文字符或數字開始,替換掉信息中的全部中英文空格,以英文或數字開始的信息不處理 if (!(firstChar >= 'a' && firstChar <= 'z' || firstChar >= 'A' && firstChar <= 'Z' || firstChar >= '0' && firstChar <= '9')) { result = result.replaceAll(" ", "").replaceAll(" ", ""); } } } } catch (Exception e) { e.printStackTrace(); } return result; } } /** * 截取字符串中的內碼 * * @param str * @return */ public String subStr(String str) { for (int i = 0; i < str.length(); i++) { // 韓文等亂碼,均以&#開頭以;結束的字符 if (str.indexOf("&#") >= 0 && str.indexOf(";", str.indexOf("&#")) > 0) { String s2 = str.substring(str.indexOf("&#"), str.indexOf(";", str.indexOf("&#")) + 1); s2 = this.cov(s2); str = str.substring(0, str.indexOf("&#")) + s2 + str.substring( str.indexOf(";", str.indexOf("&#")) + 1, str .length()); } } return str; } /** * 轉化編碼,韓文等亂碼 * * @param string * @return */ public String cov(String string) { String str = string.replaceAll("&#", ",").replaceAll(";", ""); String[] s2 = str.split(","); String s1 = ""; for (int i = 1; i < s2.length; i++) { int a = Integer.parseInt(s2[i], 10); s1 = s1 + (char) a; } return s1; } /** * 測試 * @param args */ public static void main(String[] args) { File file = new File("D:/test.xlsx"); // 保存Excel文件到服務器 String[][] dataArray = new MyExcelReader().readExcel(file); // System.out.println("標題:"+dataArray[0].toString()); for (int i = 0; i < dataArray.length; i++) { String[] rowData = dataArray[i]; for (int j = 0; j < rowData.length; j++) { System.out.println("第" + (i + 1) + "行第" + (j + 1) + "列:" + dataArray[i][j]); } } } }
3、使用freemarker導出excel
貌似是隻支持office2007以後的版本,wps也會出問題。
先放兩個連接供參考:
http://blog.csdn.net/zgf19930504/article/details/50804122
http://www.javashuo.com/article/p-vufotoya-go.html
4、第三方插件Java Excel(jxl)操做excel
http://blog.csdn.net/jerehedu/article/details/45195359
參考文章: