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(); }
.