方式一:使用POI,Apache POI是基于Office Open XML标准(OOXML)和Microsoft的OLE 2复合文档格式(OLE2)处理各种文件格式的开源项目。 简而言之,您可以使用Java读写MS Excel文件,可以使用Java读写MS Word和MS PowerPoint文件。
<dependencies> <!--xlsx(03)--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <!--xlsx(07)--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency> <!--日期格式化工具--> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.10.6</version> </dependency> <!--test--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> </dependencies>
public void testWrite03() throws Exception{ //创建一个工作簿 03 HSSFWorkbook(),07 XSSFWorkbook() 07升级 SXSSFWorkbook() Workbook workbook = new HSSFWorkbook(); //创建一个工作表 Sheet sheet = workbook.createSheet("学生表"); //创建一个行 Row row1 = sheet.createRow(0); //创建一个单元格 Cell cell11 = row1.createCell(0); cell11.setCellValue("姓名"); Cell cell12 = row1.createCell(1); cell12.setCellValue("张三"); //创建第二行 Row row2 = sheet.createRow(1); Cell cell21 = row2.createCell(0); cell21.setCellValue("统计时间"); Cell cell22 = row2.createCell(1); String time = new DateTime().toString("yyyy-MM-dd HH:mm:ss"); cell22.setCellValue(time); //生成一张表 03用xls结尾 07用xslx结尾 FileOutputStream fileOutputStream = new FileOutputStream(PATH + "学生表.xls"); //输出 workbook.write(fileOutputStream); //关闭流 fileOutputStream.close(); System.out.println("学生表生成完毕"); }
String PATH ="F:\\英雄时刻\\91662429\\kuang-poi"; @Test public void testRe03() throws Exception { //创建一个工作簿 03 HSSFWorkbook(),07XSSFWorkbook() //获取文件流: FileInputStream fileInputStream = new FileInputStream(PATH +"学生表.xls"); Workbook workbook = new HSSFWorkbook(fileInputStream); //得到表 Sheet sheet = workbook.getSheetAt(0); //得到行 Row row = sheet.getRow(0); //得到列 Cell cell = row.getCell(0); System.out.println(cell.getStringCellValue()); fileInputStream.close(); }
public void testCellType() throws Exception{ //获取文件流: FileInputStream fileInputStream = new FileInputStream(PATH + "人员类别表.xls"); Workbook workbook = new HSSFWorkbook(fileInputStream); Sheet sheet = workbook.getSheetAt(0); //获取标题内容 Row rowTitle = sheet.getRow(0); if(rowTitle !=null){ int cellcount = rowTitle.getPhysicalNumberOfCells(); for (int cellNumber = 0; cellNumber <cellcount ; cellNumber++) { Cell cell = rowTitle.getCell(cellNumber); if(cell!=null){ int cellType = cell.getCellType(); String cellValue = cell.getStringCellValue(); System.out.print(cellValue+" 丨 "); } } System.out.println(); } int rowCount = sheet.getPhysicalNumberOfRows(); for (int rowNumber = 0; rowNumber < rowCount; rowNumber++) { Row rowData = sheet.getRow(rowNumber); if(rowData != null){ //读取每行中的列 int cellCount = rowTitle.getPhysicalNumberOfCells(); for (int cellNumber = 0; cellNumber <cellCount ; cellNumber++) { System.out.println("["+(rowNumber+1)+ "-" +(cellNumber+1)+"]"); Cell cell = rowData.getCell(cellNumber); if(cell !=null){ int cellType = cell.getCellType(); String cellValue = ""; switch(cellType){ case HSSFCell.CELL_TYPE_STRING://字符串 cellValue = cell.getStringCellValue(); break; case HSSFCell.CELL_TYPE_BOOLEAN: //布尔类型 cellValue = String.valueOf(cell.getBooleanCellValue()); break; case HSSFCell.CELL_TYPE_BLANK: //空 break; case HSSFCell.CELL_TYPE_NUMERIC: //数字 if(HSSFDateUtil.isCellDateFormatted(cell)){ Date date = cell.getDateCellValue(); cellValue = new DateTime().toString("yyyy-MM-dd"); }else{ cell.setCellType(HSSFCell.CELL_TYPE_STRING); cellValue = cell.toString(); } break; case HSSFCell.CELL_TYPE_ERROR: System.out.println("数据类型错误"); break; } System.out.print(cellValue); } } } } fileInputStream.close(); }
public void testCellType( FileInputStream fileInputStream) throws Exception
方式二:(比较推荐)easyExcel
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.0-beta2</version> </dependency>
@Data public class DemoData { @ExcelProperty("字符串标题") private String string; @ExcelProperty("日期标题") private Date date; @ExcelProperty("数字标题") private Double doubleData; /** * 忽略这个字段 */ @ExcelIgnore private String ignore; }
1 public class EasyTest { 2 String PATH ="F:\\英雄时刻\\91662429\\kuang-poi\\"; 3 private List<DemoData> data() { 4 List<DemoData> list = new ArrayList<DemoData>(); 5 for (int i = 0; i < 10; i++) { 6 DemoData data = new DemoData(); 7 data.setString("字符串" + i); 8 data.setDate(new Date()); 9 data.setDoubleData(0.56); 10 list.add(data); 11 } 12 return list; 13 } 14 // 15 /** 16 * 最简单的写 17 * <p>1. 创建excel对应的实体对象 参照{@link DemoData} 18 * <p>2. 直接写即可 19 */ 20 @org.junit.Test 21 public void simpleWrite() { 22 // 写法1 23 String fileName = PATH + "EasyTest.xlsx"; 24 // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 25 EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data()); 26 27 } 28 29 }
1 public class DemoDAO { 2 public void save(List<DemoData> list) { 3 //持久化操作 4 // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入 5 } 6 }
1 package com.kuang.easy; 2 3 import com.alibaba.excel.context.AnalysisContext; 4 import com.alibaba.excel.event.AnalysisEventListener; 5 import com.alibaba.fastjson.JSON; 6 import org.slf4j.Logger; 7 import org.slf4j.LoggerFactory; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去 13 public class DemoDataListener extends AnalysisEventListener<DemoData> { 14 private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class); 15 /** 16 * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 17 */ 18 private static final int BATCH_COUNT = 5; 19 List<DemoData> list = new ArrayList<DemoData>(); 20 /** 21 * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。 22 */ 23 private DemoDAO demoDAO; 24 public DemoDataListener() { 25 // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数 26 demoDAO = new DemoDAO(); 27 } 28 /** 29 * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来 30 * 31 * @param demoDAO 32 */ 33 public DemoDataListener(DemoDAO demoDAO) { 34 this.demoDAO = demoDAO; 35 } 36 /** 37 * 这个每一条数据解析都会来调用 38 * 39 * @param data 40 * one row value. Is is same as {@link AnalysisContext#readRowHolder()} 41 * @param context 42 */ 43 44 //读取数据会执行这个方法invoke() 45 @Override 46 public void invoke(DemoData data, AnalysisContext context) { 47 // LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data)); 48 System.out.println(JSON.toJSONString(data)); 49 list.add(data); 50 // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM 51 if (list.size() >= BATCH_COUNT) { 52 saveData(); 53 // 存储完成清理 list 54 list.clear(); 55 } 56 } 57 /** 58 * 所有数据解析完成了 都会来调用 59 * 60 * @param context 61 */ 62 @Override 63 public void doAfterAllAnalysed(AnalysisContext context) { 64 // 这里也要保存数据,确保最后遗留的数据也存储到数据库 65 saveData(); 66 LOGGER.info("所有数据解析完成!"); 67 } 68 /** 69 * 加上存储数据库 70 */ 71 private void saveData() { 72 LOGGER.info("{}条数据,开始存储数据库!", list.size()); 73 demoDAO.save(list); 74 LOGGER.info("存储数据库成功!"); 75 } 76 }
测试类
1 @Test 2 public void simpleRead(){ 3 String fileName = PATH + "EasyTest.xlsx"; 4 EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead(); 5 }
原文:https://www.cnblogs.com/krifs/p/14386692.html