Apache POI(Poor Obfuscation Implementation)是用Java編寫的免費開源的跨平臺的Java API,Apache POI提供API給Java程序對Microsoft Office格式檔案讀和寫的功能,其中使用最多的就是使用POI操做Excel文件html
它是建立和維護操做各類符合Office Open XML(OOXML)標準和微軟的OLE 2複合文檔格式(OLE2)的Java API。用它可使用Java讀取和建立,修改MS Excel文件.並且,還可使用Java讀取和建立MS Word和MSPowerPoint文件。Apache POI 提供Java操做Excel解決方案(適用於Excel97-2008)
POI發行版能夠對許多文檔文件格式的支持。這種支持是在幾個JAR文件中提供的。並非每種格式都須要全部的JAR。下面我介紹一下POI組件、Maven存儲庫標記和項目的Jar文件之間的關係 【 詳細POI API 】c++
組件 操做格式 依賴 說明 XSSF Excel XLSX poi-ooxml XSLF PowerPoint PPTX poi-ooxml XWPF Word DOCX poi-ooxml XDGF Visio VSDX poi-ooxml POIFS OLE2 Filesystem poi 須要處理基於OLE2/POIFS的文件 HPSF OLE2 Property Sets poi HSSF Excel XLS poi 僅支持HSSF(只能夠操做XLS) DDF Escher common drawings poi 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 HWMF WMF drawings poi-scratchpad 特殊: Common SL: PPT和PPTX poi-scratchpad 和 poi-ooxml SL代碼在覈心POIjar中,可是實現的是poi-scratchpad和poi-ooxml Common SS: XLS和XLSX poi-ooxml WorkbookFactory和其它實現都須要poi-ooxml,而不單單是核心po OpenXML4J: OOXML poi-ooxml和poi-ooxml-lite或poi-ooxml-full
maven關於POI操做的整套依賴:apache
<!--設置maven使用什麼版本的jdk解析編譯 注意4.1.2版本的jdk編譯要是1.8及以上 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.9</maven.compiler.source> <maven.compiler.target>1.9</maven.compiler.target> </properties> <dependencies> <!--前3個座標按照上表搭配--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>4.1.2</version> </dependency> <!--poi其它依賴包,正常使用能夠不用添加--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-examples</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-excelant</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.1.2</version> </dependency> </dependencies>
XSSF是咱們最經常使用的api了,它能夠操做咱們最經常使用的Excel XLSX表格,而Excel XLS老闆格式的表格慢慢淡出了咱們的視線,由於老版格式的表格只能存在65535行,而XLSX就不會出現這個問題,我針對XSSF詳細介紹api
操做XLSX文件咱們得使用XSSFWorkbook類來構建咱們的工做簿,其實查詢繼承關係,這一類的工做簿都繼承自Workbook接口,它實現了HSSFWorkbook,SXSSFWorkbook,XSSFWorkbook等xss
public static void main(String[] args) throws IOException { //①:建立工做簿 Workbook workbook = new XSSFWorkbook(); //②:建立工做表 打開Xlsx文件最下邊的sheet一、sheet2工做表 Sheet sheet = workbook.createSheet("螞蟻小哥平常統計"); //③:經過下面2行代碼建立一個座標爲0,0 並寫上內容 對應Excel 1,1 位置 //建立行 當前建立的爲0行 對應Excel第一行 Row row = sheet.createRow(0); //建立列 當前建立列爲0列 對應Excel第一列 Cell cell = row.createCell(0); //寫入內容 今天買菜花300 cell.setCellValue("今天買菜花300"); //或者鏈式調用寫法:sheet.createRow(0).createCell(0).setCellValue("今天買菜花300"); //④:把構建的內存數據寫入到磁盤 確保有這個磁盤 OutputStream out = new FileOutputStream("h://test.xlsx"); workbook.write(out); //⑤:關閉資源 out.close(); workbook.close(); }
對於寫出的數據中包含日期類型的話,咱們就得進行樣式轉換其中操做樣式的 CellStyle 接口方法,它內部定義了各類樣式操做,如邊框顏色、對齊方式、字體、顏色等等,可是我要介紹的是樣式裏的 setDataFormat 方法,但是它接收的是short參數,這就使得我要介紹 CreationHelper 接口,它裏面的createDataFormat方法能夠建立DataFormat實例並返回short參數maven
public static void main(String[] args) throws IOException { //建立工做簿 Workbook workbook = new XSSFWorkbook(); //建立工做表 不指定名則默認Sheet(0~N) Sheet sheet = workbook.createSheet(); //建立第一行 Row row = sheet.createRow(0); //建立第一列 Cell cellA = row.createCell(0); //在0,0的位置寫入日期數據 cellA.setCellValue(new Date()); //返回一個對象,該對象處理XSSF各類實例的具體類的實例化 CreationHelper creationHelper = workbook.getCreationHelper(); //建立新的DataFormat實例。獲取與給定格式字符串匹配的格式索引,在須要時建立一個新的格式條目。 short format = creationHelper.createDataFormat().getFormat("yyyy-MM-dd"); //經過Workbook來獲取一個樣式操做類來對已有的表設置樣式 CellStyle cellStyle = workbook.createCellStyle(); //把日期格式設置噹噹前樣式cellStyle中 cellStyle.setDataFormat(format); //在1,1位置寫入日期數據 並對1,1位置寫入樣式 Cell cellB = row.createCell(1); cellB.setCellValue(new Date()); cellB.setCellStyle(cellStyle); //把構建的內存數據寫入到磁盤 OutputStream out = new FileOutputStream("h://test1.xlsx"); workbook.write(out); //關閉資源 out.close(); workbook.close(); }
public static void main(String[] args) throws IOException { //建立工做簿 Workbook workbook = new XSSFWorkbook(); //建立工做表 不指定名則默認Sheet(0~N) Sheet sheet = workbook.createSheet(); Row row = sheet.createRow(0); row.createCell(0).setCellValue("我是字符串"); row.createCell(1).setCellValue(25.5555); row.createCell(2).setCellValue(true); //對0,3 0,4 時間類和日曆類 row.createCell(3).setCellValue(new Date()); row.createCell(4).setCellValue(Calendar.getInstance()); //把構建的內存數據寫入到磁盤 OutputStream out = new FileOutputStream("h://test1.xlsx"); workbook.write(out); //關閉資源 out.close(); workbook.close(); }
學完基礎的咱們就能夠本身動手寫個簡單的建立xlsx格式的文件了,再接下來的幾節我將建立更好看的樣式表格及讀xlsx文件ide
public static void main(String[] args) throws IOException { //建立數據源 Object[] title = {"ID", "姓名", "零花錢", "生日", "是否被刪除"}; Object[] stu1 = {"tx001", "許齡月", 66.66, new Date(), true}; Object[] stu2 = {"tx002", "周星馳", 66.66, new Date(213465654L), false}; List<Object[]> list = new ArrayList<>(); list.add(title); list.add(stu1); list.add(stu2); //建立工做簿 Workbook workbook = new XSSFWorkbook(); //建立工做表 Sheet sheet = workbook.createSheet("總結"); //循環建立 for (int r = 0; r < list.size(); r++) { //建立行 Row row = sheet.createRow(r); for (int c = 0; c < list.get(r).length; c++) { if (r == 0) { //標題寫入 //建立列 Cell cell = row.createCell(c); cell.setCellValue(list.get(r)[c].toString()); } else { Object o = list.get(r)[c]; //獲取每一個單元格數據而後匹配類型 //建立列 Cell cell = row.createCell(c); //此時數據是要改變樣式 if (o instanceof Date) { CellStyle cellStyle = workbook.createCellStyle(); cellStyle.setDataFormat(workbook.getCreationHelper().createDataFormat().getFormat("yyyy-mm-dd")); cell.setCellValue((Date) list.get(r)[c]); cell.setCellStyle(cellStyle); } else { //寫入正文 cell.setCellValue(list.get(r)[c].toString()); } } } } //寫出及關閉 OutputStream out = new FileOutputStream("h:\\test02.xlsx"); workbook.write(out); out.close(); workbook.close(); }
遍歷數據可謂是重點了,咱們得建立一個工做簿並傳入xlsx文件,其中獲取起始行和結尾行則使用 getFirstRowNum 和 getLastRowNum 方法,可是獲取的每一個單元格表格數據類型不一樣則須要使用類型匹配函數
public static void main(String[] args) throws IOException { //建立工做簿並傳入一個真實存在的文件 Workbook workbook = new XSSFWorkbook("h:\\abc.xlsx"); //獲取文件的第一個工做表 Sheet sheetAt = workbook.getSheetAt(0); //獲取工做表中的起始行 int rowStart = Math.max(0, sheetAt.getFirstRowNum()); //獲取工做表中的結束行,若是大於21行則按照21行讀 0開始-20 int rowEnd = Math.min(20, sheetAt.getLastRowNum()); //循環行rowStart ~ rowEnd for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { //建立行實例 Row row = sheetAt.getRow(rowNum); //爲空則所有結束 if (row == null) { continue; } //不爲空則建立每行的列 lastColumn 若是讀到的行數大於11行則按照11行讀取 int lastColumn = Math.min(10, row.getLastCellNum()); //循環每行的列0 ~ lastColumn for (int colNum = 0; colNum < lastColumn; colNum++) { //建立列的實例 Cell cell = row.getCell(colNum); //列爲空的話就跳出循環去遍歷下一列 if (cell == null) { continue; } else { //switch來匹配類型 ,由於表格的每一個類型不同 switch (cell.getCellType()) { case NUMERIC: //數字類型 (這個相對複雜,還要判斷是數字仍是日期) //經過查找StylesSource獲取格式字符串的內容 String formatString = cell.getCellStyle().getDataFormatString(); //判斷當前的字符串形式的內容是否以m/d/yy的日期格式 if (formatString.equals("m/d/yy")) { System.out.print(cell.getDateCellValue() + " | "); } else { System.out.print(cell.getNumericCellValue() + " | "); } break; case STRING: //字符串類型 System.out.print(cell.getStringCellValue() + " | "); break; case BOOLEAN: //真假值 System.out.print(cell.getBooleanCellValue() + " | "); break; case ERROR: //錯誤類型 System.out.print(cell.getErrorCellValue() + " | "); break; case BLANK: //空數據 System.out.print("空數據" + " | "); break; case FORMULA: //計算類型 System.out.print(cell.getCellFormula() + " | "); case _NONE: //未知類型 System.out.print("未知類型" + " | "); } } } System.out.println(); } workbook.close(); }
說到對齊方式咱們就得談談2個枚舉類了 HorizontalAlignment(水平對齊)VerticalAlignment(垂直對齊),可是咱們設置對齊方式還得藉助CellStyle樣式接口內部的實現類完成,經過 setAlignment 和 setVerticalAlignment 方法來對單元格設置對齊方式工具
public static void main(String[] args) throws IOException { //建立工做簿和建立工做表 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); //設置行 Row row = sheet.createRow(0); //設置行高度 row.setHeightInPoints(60); //建立0,1單元格 Cell cell = row.createCell(1); cell.setCellValue("啦啦"); //建立樣式 CellStyle cellStyle = workbook.createCellStyle(); //設置單元格的水平對齊類型。 此時水平居中 cellStyle.setAlignment(HorizontalAlignment.CENTER); //設置單元格的垂直對齊類型。 此時垂直靠底邊 cellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM); //把樣式設置到單元格上 cell.setCellStyle(cellStyle); //寫出及關閉 OutputStream out = new FileOutputStream("h:\\test03.xlsx"); workbook.write(out); out.close(); workbook.close(); }
感受這個用處並不大,要設置漂亮樣式可使用一番 主要是經過 CellStyle 來設置邊框和邊框顏色,具體的就得參照BorderStyle、IndexedColors這2個枚舉類來獲取具體的樣式佈局
public static void main(String[] args) throws IOException { //建立工做簿和建立工做表 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); //設置行 Row row = sheet.createRow(1); //爲了能夠看到樣式 特意設置大高度 row.setHeightInPoints(60); //建立0,1單元格 Cell cell = row.createCell(1); cell.setCellValue("啦"); //建立樣式 CellStyle cellStyle = workbook.createCellStyle(); //經過set設置邊框樣式及邊框顏色 反之經過get能夠獲取設置的樣式 cellStyle.setBorderBottom(BorderStyle.DOTTED); cellStyle.setBottomBorderColor(IndexedColors.GREEN.getIndex()); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setTopBorderColor(IndexedColors.CORAL.getIndex()); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setLeftBorderColor(IndexedColors.RED.getIndex()); cellStyle.setBorderRight(BorderStyle.DASH_DOT_DOT); cellStyle.setRightBorderColor(IndexedColors.AQUA.getIndex()); //別忘了把剛纔這些設置的樣式設置到單元格上 cell.setCellStyle(cellStyle); //寫出及關閉 OutputStream out = new FileOutputStream("h:\\test03.xlsx"); workbook.write(out); out.close(); workbook.close(); }
有時候咱們會對單元格前景/背景進行色彩設置,以及對單元格的填充圖案,這時候咱們就會用到樣式類裏面的填充方法,具體看代碼
public static void main(String[] args) throws IOException { //建立工做簿和建立Sheet0工做表 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); //設置第一列的寬度是20個字符寬度 sheet.setColumnWidth(1, 20*256); //建立第一行 Row row = sheet.createRow(1); row.setHeightInPoints(60); //建立樣式對象 CellStyle style = workbook.createCellStyle(); //設置背景色 style.setFillBackgroundColor(IndexedColors.AQUA.getIndex()); //設置填充圖案(紋理)填充圖案默認爲黑色 style.setFillPattern(FillPatternType.BIG_SPOTS); //此時我設置填充圖案(前景色爲紅色) style.setFillForegroundColor(IndexedColors.RED.getIndex()); //建立行(1,1)並設置文本加樣式 Cell cell = row.createCell(1); cell.setCellValue("螞蟻小哥"); cell.setCellStyle(style); //建立流並寫出文件關閉流 OutputStream out = new FileOutputStream("h:\\test3.xlsx"); workbook.write(out); out.close(); workbook.close(); }
<!--Enum FillPatternType:--> <!--Enum:IndexedColors:--> 常量名 漢譯 常量名 漢譯 常量名 漢譯 常量名 漢譯 ALT_BARS: 寬點 BLACK: 黑色 GREEN: 綠色 DARK_RED:深紅色 BIG_SPOTS: 大斑點 BLACK1: 黑色1 VIOLET: 紫羅蘭 DARK_BLUE: 深藍色 BRICKS: 磚狀佈局 WHITE: 白色 TEAL: 藍綠色 DARK_YELLOW:深黃色 DIAMONDS: 鑽石 WHITE1: 白色1 MAROON: 栗色 DARK_GREEN: 深綠色 FINE_DOTS: 小細點 RED: 紅色 ROSE: 粉紅色 DARK_TEAL: 深青色 LEAST_DOTS: 最小點 RED1: 紅色1 AQUA: 水綠色 LIGHT_GREEN: 淺綠色 LESS_DOTS: 少點 BRIGHT_GREEN:亮綠色 LIME: 石灰色 LIGHT_YELLOW: 淺黃色 NO_FILL: 無背景 BRIGHT_GREEN1:亮綠色1 GOLD: 金 LIGHT_ORANGE:淡橙色 SOLID_FOREGROUND: 實填 BLUE: 藍色 LAVENDER:淡紫色 LIGHT_BLUE: 淺藍色 SPARSE_DOTS: 稀疏點 BLUE1: 藍色1 BROWN: 棕色 LIGHT_CORNFLOWER_BLUE:淺矢車菊藍 SQUARES: 正方形 YELLOW: 黃色 PLUM: 紫紅色 PALE_BLUE: 淡藍色 THICK_BACKWARD_DIAG:厚厚的後向對角線 YELLOW1: 黃色1 INDIGO: 靛藍色 SEA_GREEN: 海綠色 THICK_FORWARD_DIAG: 厚正面對角線 PINK: 粉紅 TAN: 棕黃色 BLUE_GREY: 藍灰 THICK_HORZ_BANDS: 厚水平帶 PINK1: 粉色1 ORCHID: 蘭花色 SKY_BLUE: 天空藍色 THICK_VERT_BANDS: 厚垂直帶 TURQUOISE: 青綠色 CORAL: 珊瑚色 GREY_25_PERCENT:灰25% THIN_BACKWARD_DIAG: 薄後向對角線 TURQUOISE1: 青綠色1 ROYAL_BLUE:皇家藍 GREY_40_PERCENT:灰40% THIN_FORWARD_DIAG: 細正對角線 LEMON_CHIFFON: 檸檬雪紡 ORNFLOWER_BLUE:矢車菊藍 GREY_50_PERCENT:灰50% THIN_HORZ_BANDS: 薄水平帶 LIGHT_TURQUOISE:淺青綠色 ORANGE: 桔黃色的 GREY_80_PERCENT:灰80% THIN_VERT_BANDS: 薄垂直帶 LIGHT_TURQUOISE1:淺青綠色1 OLIVE_GREEN: 橄欖綠 AUTOMATIC:天然色
有時候咱們要設置單元格的合併,這個時候咱們就可使用addMergedRegion方法完成
public static void main(String[] args) throws IOException { //建立工做簿和建立Sheet0工做表 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); //設置單元格合併 //第一個參數和第二個參數設置左位置(1,1) 0開始 //第三個參數和第四個參數設置右位置(1,5) 0開始 //鏈接2點的範圍的形狀就是單元格合併的範圍 注意只是合併單元格 不能跨行!!想單元格高點就設置高度 sheet.addMergedRegion(new CellRangeAddress(1,1,1,5)); //建立行 Row row = sheet.createRow(1); //建立列此時爲1,1 併爲單元格設置信息 Cell cell = row.createCell(1); cell.setCellValue("螞蟻小哥"); //建立流並寫出文件關閉流 OutputStream out = new FileOutputStream("h:\\test3.xlsx"); workbook.write(out); out.close(); workbook.close(); }
對字體的設置咱們得經過工做簿先建立字體樣式類,而後再進行字體的設置
public static void main(String[] args) throws IOException { //建立工做簿和建立Sheet0工做表 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); //建立行 Row row = sheet.createRow(1); //建立字體類 Font font = workbook.createFont(); //設置字體顏色 font.setColor(IndexedColors.RED1.getIndex()); //設置字體 true粗體(默認) false細 font.setBold(false); //設置字體大小 font.setFontHeightInPoints((short) 60); //設置字體名 如楷體,微軟雅黑....中文和英文表示都行 font.setFontName("楷體"); //傾斜設置 font.setItalic(true); //設置刪除線 font.setStrikeout(true); //建立樣式類 CellStyle cellStyle = workbook.createCellStyle(); //樣式設置font樣式 cellStyle.setFont(font); //建立列此時爲1,1 併爲單元格設置信息 Cell cell = row.createCell(1); cell.setCellValue("螞蟻小哥"); cell.setCellStyle(cellStyle); //建立流並寫出文件關閉流 OutputStream out = new FileOutputStream("h:\\test3.xlsx"); workbook.write(out); out.close(); workbook.close(); }
經過上面的樣式建立和單元格的建立咱們發現,每次設置樣式都要建立對象,麻煩,還浪費內存,其實ReginUtil(區域工具)CellUtil(樣式工具)能夠很快構建咱們的樣式,能夠簡寫不少代碼
public static void main(String[] args) throws IOException { //建立工做簿和建立Sheet0工做表 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("new sheet"); //建立2行 對應表中的第1行和第2行 0開始 Row row = sheet.createRow(1); Row row2 = sheet.createRow(2); //建立1,1的單元格 Cell cell = row.createCell(1); cell.setCellValue("螞蟻小哥"); //此類能夠建立單元格的範圍 B2(1,1):E5(4,4) CellRangeAddress region = CellRangeAddress.valueOf("B2:E5"); //傳遞給合併單元格方法裏 sheet.addMergedRegion(region); //設置四邊樣式及顏色 可是得傳遞Sheet和CellRangeAddress RegionUtil.setBorderBottom(BorderStyle.MEDIUM_DASHED, region, sheet); RegionUtil.setBorderTop(BorderStyle.MEDIUM_DASHED, region, sheet); RegionUtil.setBorderLeft(BorderStyle.MEDIUM_DASH_DOT, region, sheet); RegionUtil.setBorderRight(BorderStyle.MEDIUM_DASHED, region, sheet); RegionUtil.setBottomBorderColor(IndexedColors.BLUE.getIndex(), region, sheet); RegionUtil.setTopBorderColor(IndexedColors.AQUA.getIndex(), region, sheet); RegionUtil.setLeftBorderColor(IndexedColors.RED.getIndex(), region, sheet); RegionUtil.setRightBorderColor(IndexedColors.AQUA.getIndex(), region, sheet); //建立樣式類 CellStyle style = workbook.createCellStyle(); //設置空格數以縮進單元格中的文本 style.setIndention((short) 4); CellUtil.createCell(row, 8, "my name is ant", style); Cell cell2 = CellUtil.createCell(row2, 8, "阿三大蘇打"); //設置居中 CellUtil.setAlignment(cell2, HorizontalAlignment.CENTER); //建立流並寫出文件關閉流 OutputStream out = new FileOutputStream("h:\\test3.xlsx"); workbook.write(out); out.close(); workbook.close(); }
.