1. Apache POI
1.1 环境准备
<dependencies>
<!--xls(03)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<!--xlsx(07)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!--时间格式化工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.6</version>
</dependency>
</dependencies>
在poi工具库中,导出的api可以分为三种方式:
1). HSSF方式:这种方式导出的文件格式为office 2003专用格式,即.xls,优点是导出数据速度快,但是最多导出65535行数据;
2). XSSF方式:这种方式导出的文件格式为office 2007专用格式,即.xlsx,优点是导出数据不受行数限制,缺点是导出速度慢;
3). SXSSF方式:SXSSF是XSSF api的兼容流式扩展,主要解决当使用XSSF方式导出大数据量时,内存溢出的问题,支持导出大批量的excel数据;
1.2 HSSF方式导出
HSSF最多支持65535条数据导出,超过该条数会报错;
package cn.tedu.excel.test; import org.apache.poi.hssf.usermodel.HSSFWorkbook; 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 java.io.FileOutputStream; /** * HSSF方式导出:HSSF方式,最多只支持65536条数据导出,超过这个条数会报错! * 就是.xls模式 */ public class ExcelWrite2003Test { private static String PATH = "/Users/lixin/Desktop/";//自己输出的路径 public static void main(String[] args) throws Exception { //时间 long begin = System.currentTimeMillis(); //创建一个工作簿 Workbook workbook = new HSSFWorkbook(); //创建表 Sheet sheet = workbook.createSheet(); //写入数据 for (int rowNumber = 0; rowNumber < 65536; rowNumber++) { //创建行 Row row = sheet.createRow(rowNumber); for (int cellNumber = 0; cellNumber < 10; cellNumber++) { //创建列 Cell cell = row.createCell(cellNumber); cell.setCellValue(cellNumber); } } System.out.println("结束!"); FileOutputStream fileOutputStream = new FileOutputStream(PATH + "用户信息表-XLS.xls"); workbook.write(fileOutputStream); fileOutputStream.close(); long end = System.currentTimeMillis(); System.out.println("时间为:"+(double) (end - begin) / 1000);//2.262s } }
1.3 XSSF方式导出
XSSF方式支持大批量数据导出,所有的数据先写入内存再导出,容易出现内存溢出;
package cn.tedu.excel.test; 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.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; /** * .xlsx方式 */ public class ExcelWrite2007Test { public static String PATH = "/Users/lixin/Desktop/"; public static void main(String[] args) throws Exception { //时间 long begin = System.currentTimeMillis(); //创建一个工作簿 Workbook workbook = new XSSFWorkbook(); //创建表 Sheet sheet = workbook.createSheet(); //写入数据 for (int rowNumber = 0; rowNumber < 65537; rowNumber++) { Row row = sheet.createRow(rowNumber); for (int cellNumber = 0; cellNumber < 10; cellNumber++) { Cell cell = row.createCell(cellNumber); cell.setCellValue(cellNumber); } } System.out.println("结束"); FileOutputStream fileOutputStream = new FileOutputStream(PATH + "用户信息表-XLSX.xlsx"); workbook.write(fileOutputStream); fileOutputStream.close(); long end = System.currentTimeMillis(); System.out.println((double) (end - begin) / 1000);//5.003s } }
1.3 SXSSF方式导出
SXSSF是XSSF方式的一种延伸,主要特性是低内存,导出时候先将数据写入到磁盘再导出,避免报内存不足,导致程序运行异常,缺点是运行速度很慢;
package cn.tedu.excel.test; 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.xssf.streaming.SXSSFWorkbook; import java.io.FileOutputStream; public class ExcelWriteSXSSFTest { public static String PATH = "/Users/lixin/Desktop/"; public static void main(String[] args) throws Exception { //时间 long begin = System.currentTimeMillis(); //创建一个工作簿 Workbook workbook = new SXSSFWorkbook(); //创建表 Sheet sheet = workbook.createSheet(); //写入数据 for (int rowNumber = 0; rowNumber < 100000; rowNumber++) { Row row = sheet.createRow(rowNumber); for (int cellNumber = 0; cellNumber < 10; cellNumber++) { Cell cell = row.createCell(cellNumber); cell.setCellValue(cellNumber); } } System.out.println("over"); FileOutputStream fileOutputStream = new FileOutputStream(PATH + "用户信息表-SXSSF.xlsx"); workbook.write(fileOutputStream); fileOutputStream.close(); long end = System.currentTimeMillis(); System.out.println((double) (end - begin) / 1000);//6.39s } }
2 导入excel
2.1 HSSF方式导入
package cn.tedu.excel.test; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.*; import org.joda.time.DateTime; import java.io.FileInputStream; import java.util.Date; public class ExcelRead2003Test { public static String PATH = "/Users/lixin/Desktop/"; public static void main(String[] args) throws Exception { //获取文件流 FileInputStream inputStream = new FileInputStream(PATH + "用户信息表2003read.xls"); //1.创建工作簿,使用excel能操作的这边都看看操作 Workbook workbook = new HSSFWorkbook(inputStream); //2.得到表 Sheet sheet = workbook.getSheetAt(0); //3.得到行 Row row = sheet.getRow(0); //4.得到列 Cell cell = row.getCell(0); getValue(cell); inputStream.close(); } public static void getValue(Cell cell){ //匹配类型数据 if (cell != null) { CellType cellType = cell.getCellType(); String cellValue = ""; switch (cellType) { case STRING: //字符串 System.out.print("[String类型]"); cellValue = cell.getStringCellValue(); break; case BOOLEAN: //布尔类型 System.out.print("[boolean类型]"); cellValue = String.valueOf(cell.getBooleanCellValue()); break; case BLANK: //空 System.out.print("[BLANK类型]"); break; case NUMERIC: //数字(日期、普通数字) System.out.print("[NUMERIC类型]"); if (HSSFDateUtil.isCellDateFormatted(cell)) { //日期 System.out.print("[日期]"); Date date = cell.getDateCellValue(); cellValue = new DateTime(date).toString("yyyy-MM-dd"); } else { //不是日期格式,防止数字过长 System.out.print("[转换为字符串输出]"); cell.setCellType(CellType.STRING); cellValue = cell.toString(); } break; case ERROR: System.out.print("[数据类型错误]"); break; } System.out.println(cellValue); } } }
2.2 XSSF方式导入
package cn.tedu.excel.test; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.joda.time.DateTime; import java.io.FileInputStream; import java.util.Date; public class ExcelRead2007Test { public static String PATH = "/Users/lixin/Desktop/"; public static void main(String[] args) throws Exception { //获取文件流 FileInputStream inputStream = new FileInputStream(PATH + "用户信息表2007read.xlsx"); //1.创建工作簿,使用excel能操作的这边都看看操作 Workbook workbook = new XSSFWorkbook(inputStream); //2.得到表 Sheet sheet = workbook.getSheetAt(0); //3.得到行 Row row = sheet.getRow(0); //4.得到列 Cell cell = row.getCell(0); getValue(cell); inputStream.close(); } public static void getValue(Cell cell){ //匹配类型数据 if (cell != null) { CellType cellType = cell.getCellType(); String cellValue = ""; switch (cellType) { case STRING: //字符串 System.out.print("[String类型]"); cellValue = cell.getStringCellValue(); break; case BOOLEAN: //布尔类型 System.out.print("[boolean类型]"); cellValue = String.valueOf(cell.getBooleanCellValue()); break; case BLANK: //空 System.out.print("[BLANK类型]"); break; case NUMERIC: //数字(日期、普通数字) System.out.print("[NUMERIC类型]"); if (HSSFDateUtil.isCellDateFormatted(cell)) { //日期 System.out.print("[日期]"); Date date = cell.getDateCellValue(); cellValue = new DateTime(date).toString("yyyy-MM-dd"); } else { //不是日期格式,防止数字过长 System.out.print("[转换为字符串输出]"); cell.setCellType(CellType.STRING); cellValue = cell.toString(); } break; case ERROR: System.out.print("[数据类型错误]"); break; } System.out.println(cellValue); } } }
2.3 SXSSF方式导入
package cn.tedu.excel.test; import org.apache.poi.ooxml.util.SAXHelper; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.usermodel.XSSFComment; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; public class ExcelReadSXSSFTest { public static String PATH = "/Users/lixin/Desktop/"; public static void main(String[] args) throws Exception { //获取文件流 //1.创建工作簿,使用excel能操作的这边都看看操作 OPCPackage opcPackage = OPCPackage.open(PATH + "用户信息表2007read.xlsx"); XSSFReader xssfReader = new XSSFReader(opcPackage); StylesTable stylesTable = xssfReader.getStylesTable(); ReadOnlySharedStringsTable sharedStringsTable = new ReadOnlySharedStringsTable(opcPackage); // 创建XMLReader,设置ContentHandler XMLReader xmlReader = SAXHelper.newXMLReader(); xmlReader.setContentHandler(new XSSFSheetXMLHandler(stylesTable, sharedStringsTable, new SimpleSheetContentsHandler(), false)); // 解析每个Sheet数据 Iterator<InputStream> sheetsData = xssfReader.getSheetsData(); while (sheetsData.hasNext()) { try (InputStream inputStream = sheetsData.next();) { xmlReader.parse(new InputSource(inputStream)); } } } /** * 内容处理器 */ public static class SimpleSheetContentsHandler implements XSSFSheetXMLHandler.SheetContentsHandler { protected List<String> row; @Override public void startRow(int rowNum) { row = new ArrayList<>(); } @Override public void endRow(int rowNum) { if (row.isEmpty()) { return; } // 处理数据 System.out.println(row.stream().collect(Collectors.joining(" "))); } @Override public void cell(String cellReference, String formattedValue, XSSFComment comment) { row.add(formattedValue); } @Override public void headerFooter(String text, boolean isHeader, String tagName) { } } }
浙公网安备 33010602011771号