這周公司要用excel做爲數據存儲格式作一個文具申請的功能,感受之前原本很簡單的功能變複雜了很多,可是仍是記錄一下一些excel的基本用法。html
寫在最前面:這裏只介紹一些excel的基本存儲方式(讀,寫,數據和樣式),高級用法並不會涉及。java
首先是須要引入的jar包,以下表所示:(如下內容來自於Apache POI的官方文檔)apache
Apache POI能夠運用在許多文檔文件的格式中。這些對文檔操做的支持須要一些jar文件。不是全部的jar文件都被須要於每個格式中。下面的表格列出了在POI部件中的關係,maven倉庫的tags,和項目須要的jar文件。api
組件 | 應用類型 | Maven artifactId | 注意 |
---|---|---|---|
POIFS | OLE2 Filesystem | poi | Required to work with OLE2 / POIFS based files |
HPSF | OLE2 Property Sets | poi | |
HSSF | Excel XLS | poi | For HSSF only, if common SS is needed see below |
HSLF | PowerPoint PPT | poi-scratchpad | |
HWPF | Word DOC | poi-scratchpad | |
HDGF | Visio VSD | poi-scratchpad | |
HPBF | Publisher PUB | poi-scratchpad | |
HSMF | Outlook MSG | poi-scratchpad | |
DDF | Escher common drawings | poi | |
HWMF | WMF drawings | poi-scratchpad | |
OpenXML4J | OOXML | poi-ooxml plus either poi-ooxml-schemasor ooxml-schemas and ooxml-security |
See notes below for differences between these options |
XSSF | Excel XLSX | poi-ooxml | |
XSLF | PowerPoint PPTX | poi-ooxml | |
XWPF | Word DOCX | poi-ooxml | |
Common SL | PowerPoint PPT and PPTX | poi-scratchpad and poi-ooxml | SL code is in the core POI jar, but implementations are in poi-scratchpad and poi-ooxml. |
Common SS | Excel XLS and XLSX | poi-ooxml | WorkbookFactory and friends all require poi-ooxml, not just core poi |
下面是maven倉庫所須要的jar包:數組
Maven artifactId | 預先準備 | JAR |
---|---|---|
poi | commons-logging, commons-codec, log4j | poi-version-yyyymmdd.jar |
poi-scratchpad | poi | poi-scratchpad-version-yyyymmdd.jar |
poi-ooxml | poi, poi-ooxml-schemas | poi-ooxml-version-yyyymmdd.jar |
poi-ooxml-schemas | xmlbeans | poi-ooxml-schemas-version-yyyymmdd.jar |
poi-examples | poi, poi-scratchpad, poi-ooxml | poi-examples-version-yyyymmdd.jar |
ooxml-schemas | xmlbeans | ooxml-schemas-1.3.jar |
ooxml-security | xmlbeans For signing: bcpkix-jdk15on, bcprov-jdk15on, xmlsec, slf4j-api |
ooxml-security-1.1.jar |
綜上可知:咱們操做excel所須要poi,poi-ooxml和poi-ooxml-shemas這三類,請自行配置app
tips:excel分爲xls和xlsx,第一類是基於binary的標準,第二種是基於xml的規範,因此用不一樣的類進行操做maven
/** * 新建一個excel 2003的文件,在項目的根目錄下 */ public void createHSSFWorkBooksTest() { try { Workbook wb = new HSSFWorkbook(); //這裏新建了一個exccel 2003的文件,因此 //Workbook wb = new XSSFWorkbook(); 這裏是一個excel2007的文件,相應的輸出流後綴應該是xlsx FileOutputStream fos = new FileOutputStream("workbook.xls"); wb.write(fos); fos.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
/** * 新建一個excel 2003的文件,在項目的根目錄下 */ public void createHSSFWorkBooksTest() { try { Workbook wb = new HSSFWorkbook(); //這裏新建了一個exccel 2003的文件,因此 //Workbook wb = new XSSFWorkbook(); 這裏是一個excel2007的文件,相應的輸出流後綴應該是xlsx FileOutputStream fos = new FileOutputStream("workbook.xls"); wb.write(fos); fos.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
在單元格里面賦值,值爲1 ide
tips:在單元格里面能夠添加全部基本類型,以及公式,可是公式操做這裏不作介紹函數
/** * 在第二行的第一個單元格里面賦值,值爲1 * @throws Exception */ public void testCreateCell() throws Exception { Workbook wb = new HSSFWorkbook(); CreationHelper helper = wb.getCreationHelper(); Sheet sheet = wb.createSheet("new Sheet"); Row row = sheet.createRow(1); Cell cell = row.createCell(0); cell.setCellValue(1); FileOutputStream fos = new FileOutputStream("workbook.xls"); wb.write(fos); fos.close(); }
/** * 在單元格里面添加日期類型的值 * @throws Exception */ public void testCreateDateCell() throws Exception { //新建一個excel2003的workbook Workbook wb = new HSSFWorkbook(); //新建一個單元格 Sheet sheet = wb.createSheet(); CreationHelper helper = wb.getCreationHelper(); //新建一行,且是第一行,java中的行是從0開始計算的 Row row = sheet.createRow(0); //在第一行新建一個單元格 Cell cell = row.createCell(0); //在這裏賦一個沒有轉換格式的日期類型 cell.setCellValue(new Date()); //經過workbook得到一個cellstyle CellStyle style = wb.createCellStyle(); //進行日期類型的格式轉換 style.setDataFormat(helper.createDataFormat().getFormat("m/d/yy h:mm")); //新建一個單元格,單元格的位置是第一行第二列 cell = row.createCell(1); //賦值,變量爲日期類型 cell.setCellValue(new Date()); //該單元格的style爲上面的那種 cell.setCellStyle(style); cell = row.createCell(2); //第二種得到日期的方法,經過調用java的canlendar cell.setCellValue(Calendar.getInstance()); cell.setCellStyle(style); FileOutputStream fos = new FileOutputStream("workbook.xls"); wb.write(fos); fos.close(); }
/** * 設置不一樣的顏色顯示 * @throws Exception */ public void testCreateDifferentCell() throws Exception { Workbook wb = new HSSFWorkbook(); Sheet sheet = wb.createSheet("new sheet"); Row row = sheet.createRow(2); CellStyle style = wb.createCellStyle(); //獲取一個font Font font = wb.createFont(); //設置font的顏色爲紅色 font.setColor(Font.COLOR_RED); style.setFont(font); row.createCell(0).setCellValue(1.2); row.getCell(0).setCellStyle(style); row.createCell(1).setCellValue(1); row.createCell(2).setCellValue(true); FileOutputStream fos = new FileOutputStream("workbook.xls"); wb.write(fos); fos.close(); }
/** * 讀取已經存在excel的兩種方式 * File && InputStream * * @throws Exception */ public void testCreateExcelByInputStreamAndFile() throws Exception { // Workbook wb = new HSSFWorkbook(); Workbook wb = WorkbookFactory.create(new File("workbook.xls")); //Workbook wb = WorkbookFactory.create(new FileInputStream("workbook.xls")); Sheet sheet = wb.createSheet("new sheet"); Row row = sheet.createRow(2); CellStyle style = wb.createCellStyle(); // style.setFont(wb.createFont().setColor(Font.COLOR_RED)); Font font = wb.createFont(); font.setColor(Font.COLOR_RED); style.setFont(font); row.createCell(0).setCellValue(1.2); row.getCell(0).setCellStyle(style); row.createCell(1).setCellValue(1); row.createCell(2).setCellValue(true); wb.close(); // FileOutputStream fos = new FileOutputStream("workbook.xls"); // wb.write(fos); // fos.close(); }
/** * 循環excel裏面全部的元素,默認的迭代方式,不用迭代器,可是在poi3.5以前都不支持這樣的讀取方式 * @throws Exception */ public void testIterateAllExcel() throws Exception { Workbook wb = WorkbookFactory.create(new File("iterate.xls")); for (Sheet sheet : wb) { for (Row row : sheet) { for (Cell cell : row) { if (cell == null) { System.out.println("the cell is null!"); } else { System.out.println(cell.getStringCellValue()); } } } } wb.close(); }
/** * 在excel的單元格內容有各式各樣的形式,因此讀取以前要先判斷讀取內容的類型,而後才能用相應的方式讀取出來 * @throws Exception */ public void testGetExcelContent() throws Exception { Workbook wb = WorkbookFactory.create(new File("iterate.xls")); Sheet sheet = wb.getSheetAt(0); for (Row row : sheet) { for (int i = 0; i < row.getLastCellNum(); i++) { //單元格的內容若是是空則返回null Cell cell = row.getCell(i, Row.RETURN_BLANK_AS_NULL); if (cell == null) { System.out.println("the cell is null!"); continue; } //經過getCellType方法判斷單元格里面的內容 switch (cell.getCellType()) { //獲取的內容爲string類型 case Cell.CELL_TYPE_STRING: System.out.println("the type is String:" + cell.getRichStringCellValue().getString()); break; //獲取的內容爲數字類型(包括整型,浮點...) case Cell.CELL_TYPE_NUMERIC: System.out.println("the type is numeric:" + cell.getNumericCellValue()); break; //獲取的內容爲布爾類型 case Cell.CELL_TYPE_BOOLEAN: System.out.println("the type is boolean:" + cell.getBooleanCellValue()); break; //獲取的內容爲公式類型 case Cell.CELL_TYPE_FORMULA: System.out.println("the type is formula:" + cell.getCellFormula()); break; //獲取的內容爲black case Cell.CELL_TYPE_BLANK: System.out.println("the type is null:" + cell); break; default: System.out.println("-"); break; } } } wb.close(); }
/** * 讀和從新寫入,就是輸入流和輸出流都對同一個文件作操做 * @throws Exception */ public void testExcelFont() throws Exception { Workbook wb = new HSSFWorkbook(); Sheet sheet = wb.createSheet("new sheet"); Row row = sheet.createRow((short) 1); Cell cell = row.createCell((short) 1); cell.setCellValue("This is testing merge"); Font font = wb.createFont(); font.setColor(IndexedColors.BLUE.getIndex()); CellStyle style = wb.createCellStyle(); style.setFont(font); cell.setCellStyle(style); FileOutputStream fos = new FileOutputStream("workbook.xls"); wb.write(fos); wb.close(); fos.close(); }
------------------------------不知疲倦的翻越每個山丘,越過山丘,雖然已白了頭,更新於2016/09/29-------------------------------------------字體
這裏本身寫了一個類,在構造函數時傳入excel的地址,就能夠經過裏面的方法讀取指定行,指定列,以及一個sheet中的所有內容,或者讀取整個excel,而且在javabean的屬性和excel對應列高度匹配時,能夠調用方法直接轉換成bean。
附代碼:
package com.rms.apply.util; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.usermodel.Cell; 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.ss.usermodel.WorkbookFactory; import com.rms.entity.Server; public class POIExcelUtilHelper { private String excelPath; private Workbook wb = null; private InputStream inp = null; /** * the constructor method * * @param excelPath * the excel path like D://xxx.xlsx */ public POIExcelUtilHelper(String excelPath) { this.excelPath = excelPath; try { inp = new FileInputStream(excelPath); wb = WorkbookFactory.create(inp); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * read one line in excel * * @author mingzheng * @param sheet * the sheet * @param rowNum * the row line which you should read * @param startCellNum * the start column which you begin to read * @param endCellNum * the end of the column which you end to read(if the value is -1 * means read the line to the end of column) * @param notReadNum * the columns which you don't want to read * @return an array of object */ private Object[] readOneline(Sheet sheet, int rowNum, int startCellNum, int endCellNum, int... notReadNum) { List<Integer> notReadList = new ArrayList<Integer>(); for (int i = 0; i < notReadNum.length; i++) { notReadList.add(notReadNum[i]); } Row row = sheet.getRow(rowNum); if (row == null) { return null; } if (endCellNum == -1) { endCellNum = row.getLastCellNum(); } else { endCellNum++; } int objectNum = endCellNum - startCellNum - notReadNum.length; Object[] object = new Object[objectNum]; int j = 0; for (int i = startCellNum; i < endCellNum; i++) { if (notReadList.contains(i)) { System.out.println("the continue is:" + i); continue; } Cell cell = row.getCell(i); if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { if (HSSFDateUtil.isCellDateFormatted(cell)) { SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy", Locale.ENGLISH); object[j] = sdf.format(HSSFDateUtil.getJavaDate(cell .getNumericCellValue())); } else { object[j] = cell.getNumericCellValue(); } } else if (cell.getCellType() == cell.CELL_TYPE_STRING) { object[j] = cell.getStringCellValue(); } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) { try { object[j] = cell.getNumericCellValue(); } catch (IllegalStateException e) { try { object[j] = cell.getStringCellValue(); } catch (IllegalStateException e1) { object[j] = "wrong!"; } } } else { object[j] = ""; } j++; } return object; } /** * enter the sheet num and read the row and column which you want to read. * * @author mingzheng * @param sheetNum * the sheet num (begin with 0) * @param rowNum * the row line which you should read * @param startCellNum * the start column which you begin to read * @param endCellNum * the end of the column which you end to read(if the value is -1 * means read the line to the end of column) * @param notReadNum * the columns which you don't want to read * @return an array of object */ public Object[] readOneObject(int sheetNum, int rowNum, int startCellNum, int endCellNum, int... notReadNum) { Sheet sheet = wb.getSheetAt(sheetNum); Object[] objects = readOneline(sheet, rowNum, startCellNum, endCellNum, notReadNum); return objects; } /** * enter the sheet name and read the row and column which you want to read. * * @author mingzheng * @param sheetNum * the sheet name * @param rowNum * the row line which you should read * @param startCellNum * the start column which you begin to read * @param endCellNum * the end of the column which you end to read(if the value is -1 * means read the line to the end of column) * @param notReadNum * the columns which you don't want to read * @return an array of object */ public Object[] readOneObject(String sheetName, int rowNum, int startCellNum, int endCellNum, int... notReadNum) { Sheet sheet = wb.getSheet(sheetName); Object[] objects = readOneline(sheet, rowNum, startCellNum, endCellNum, notReadNum); return objects; } /** * 讀取excel裏面指定行和指定列,而且返回一個list包裝的object數組 * * @param sheetName * sheet的名字 * @param startRowNum * 開始的行號 * @param endRowNum * 結束的行號 * @param startCellNum * 開始的列號 * @param endCellNum * 結束的列號 * @param notReadNum * 在開始和結束列之間不用讀的列號 * @return list包裝的object數組 */ public List<Object[]> readListObject(String sheetName, int startRowNum, int endRowNum, int startCellNum, int endCellNum, int... notReadNum) { List<Object[]> oList = new ArrayList<Object[]>(); Sheet sheet = wb.getSheet(sheetName); if (endRowNum == -1) { endRowNum = sheet.getLastRowNum() + 1; } else { endRowNum++; } for (int i = startRowNum; i < endRowNum + 1; i++) { Object[] objects = readOneline(sheet, i, startCellNum, endCellNum, notReadNum); oList.add(objects); } return oList; } /** * 讀一個excel的指定行和指定列,而且返回一個list包裝的object數組 * * @param sheetNum * sheet的位置號 * @param startRowNum * 開始的行號 * @param endRowNum * 結束的行號 * @param startCellNum * 開始的列號 * @param endCellNum * 結束的列號 * @param notReadNum * 在開始行和結束行之間不用讀的行號 * @return list包裝的object數組 */ public List<Object[]> readListObject(int sheetNum, int startRowNum, int endRowNum, int startCellNum, int endCellNum, int... notReadNum) { List<Object[]> oList = new ArrayList<Object[]>(); Sheet sheet = wb.getSheetAt(sheetNum); if (endRowNum == -1) { endRowNum = sheet.getLastRowNum() + 1; } else { endRowNum++; } for (int i = startRowNum; i < endRowNum; i++) { Object[] objects = readOneline(sheet, i, startCellNum, endCellNum, notReadNum); oList.add(objects); } return oList; } /** * 讀整個excel * * @return 返回一個map,key是sheet的名字,value是每個sheet對應的list */ public Map<String, List<Object[]>> readAllExcel() { Map<String, List<Object[]>> map = new HashMap<String, List<Object[]>>(); int sheetNum = wb.getNumberOfSheets(); for (int i = 0; i < sheetNum; i++) { String sheetName = wb.getSheetName(i); List<Object[]> oList = readListObject(i, 0, -1, 0, -1); map.put(sheetName, oList); } return map; } public Object transferArrayToObject(Class clazz, Object[] objects) { try { Object object = clazz.newInstance(); Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < objects.length; i++) { Field field = fields[i]; field.setAccessible(true); if ((field.getType() == int.class || field.getType() == Integer.class) && (objects[i] instanceof Double)) { System.out.println(objects[i]); Double tempValue = (Double) objects[i]; objects[i] = tempValue.intValue(); } field.set(object, objects[i]); } return object; } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } public Object readOneObjectToBean(Class clazz, int sheetNum, int rowNum, int startCellNum, int endCellNum, int... notReadNum) { Object[] objectArray = readOneObject(sheetNum, rowNum, startCellNum, endCellNum, notReadNum); return transferArrayToObject(clazz, objectArray); } public Object readOneObjectToBean(Class clazz, String sheetName, int rowNum, int startCellNum, int endCellNum, int... notReadNum) { Object[] objectArray = readOneObject(sheetName, rowNum, startCellNum, endCellNum, notReadNum); return transferArrayToObject(clazz, objectArray); } public List readListObjectToBean(Class clazz, int sheetNum, int startRowNum, int endRowNum, int startCellNum, int endCellNum, int... notReadNum) { List<Object[]> oList = readListObject(sheetNum, startCellNum, endRowNum, startCellNum, endCellNum, notReadNum); List list = new ArrayList(); for (Object[] objectArray : oList) { Object object = transferArrayToObject(clazz, objectArray); list.add(object); } return list; } public List readListObjectToBean(Class clazz, String sheetName, int startRowNum, int endRowNum, int startCellNum, int endCellNum, int... notReadNum) { List<Object[]> oList = readListObject(sheetName, startCellNum, endRowNum, startCellNum, endCellNum, notReadNum); List list = new ArrayList(); for (Object[] objectArray : oList) { Object object = transferArrayToObject(clazz, objectArray); list.add(object); } return list; } public Map<String, List> readAllExcel(Class clazz) { Map<String, List<Object[]>> oMap = readAllExcel(); Map<String, List> map = new HashMap<String, List>(); for (Entry<String, List<Object[]>> entry : oMap.entrySet()) { String key = entry.getKey(); List<Object[]> oList = entry.getValue(); List list = new ArrayList(); for (Object[] objectArray : oList) { Object o = transferArrayToObject(clazz, objectArray); list.add(o); } map.put(key, list); } return map; } public static void main(String[] args) throws InvalidFormatException, IOException { POIExcelUtilHelper helper = new POIExcelUtilHelper( "D://CR Tracking List_Order_SPEAR v4 final.xlsx"); Object[] list = helper.readOneObject("CR List", 2, 0, 41, 31, 32); System.out.println(Arrays.toString(list)); System.out.println(list.length); System.out.println("read the excel end!"); } }