摘要:由于开发需要批量导入Excel中的数据,使用了Apache POI库,记录下使用过程
Java 中操作 Excel 文件的库常用的有Apache POI 和阿里巴巴的 EasyExcel 。Apache POI 是一个功能比较全面的 Java 库,适合处理复杂的 Office 文件操作需求;而 EasyExcel 则是一个专注于 Excel 文件读写的简单、高效工具,更适合处理 Excel 文件的批量读写需求,并且易于上手。当Excel的数据量很大时推荐使用EasyExcel更合适。
Apache的POI 用于处理 Microsoft Office 格式文件(如Excel、Word、PowerPoint)。它支持读取、写入和操作 Excel 文件,可以处理各种 Excel 格式(如 .xls 和 .xlsx)。
Apache POI - the Java API for Microsoft Documents
https://poi.apache.org/
首先,在pom.xml中配置相关依赖,并使用Maven引入
- <dependency>
- <groupId>org.apache.poigroupId>
- <artifactId>poiartifactId>
- <version>3.16version>
- dependency>
- <dependency>
- <groupId>org.apache.poigroupId>
- <artifactId>poi-ooxmlartifactId>
- <version>3.16version>
- dependency>
使用Apache POI解析Excel大体过程:通过输入流FileInputStream读取Excel中的数据,使用XSSFWorkbook类加载输入流,创建了一个新版本的Excel工作簿(下例子为workbook),从创建的工作簿中获取第一个工作表 firstsheet,再通过迭代器逐行逐个单元格遍历工作表,将单元格中的数据填充到对象中,并将对象添加到列表。此时,对得到的列表遍历,执行相应的数据库操作,实现批量导入的功能。
- public void addProductByExcel(File destFile) throws IOException {
- // 从Excel文件中读取商品信息,并转换为商品列表
- List
products = readProductsFromExcel(destFile); - for (int i = 0; i < products.size(); i++) {
- Product product = products.get(i);
- Product productOld = productMapper.selectByName(product.getName()); // 通过商品名称来查询数据库中是否已存在同名商品
- if (productOld != null) { // 查询到同名商品,则抛出自定义异常
- throw new ImoocMallException(ImoocMallExceptionEnum.NAME_EXISTED);
- }
- int count = productMapper.insertSelective(product); // 不存在同名商品,则向数据库中插入当前商品信息,存储受影响的行数
- if (count == 0) {
- throw new ImoocMallException(ImoocMallExceptionEnum.CREATE_FAILED);
- }
- }
- }
-
- private List
readProductsFromExcel(File excelFile) throws IOException { - ArrayList
listProducts = new ArrayList<>(); // 用于存储读取到的商品信息 - FileInputStream inputStream = new FileInputStream(excelFile); // 文件输入流 inputStream,用于读取Excel文件中的数据
-
- XSSFWorkbook workbook = new XSSFWorkbook(inputStream); // 使用XSSFWorkbook类加载输入流,创建了一个新版本的Excel工作簿workbook
- XSSFSheet firstsheet = workbook.getSheetAt(0); // 获取第一个工作表,index从0还是1开始需要根据实际情况确认
- Iterator
iterator = firstsheet.iterator(); // 通过工作表的迭代器创建一个行迭代器iterator,用于逐行遍历工作表中的数据
- while(iterator.hasNext()) {
- Row nextRow = iterator.next(); // 逐行遍历
- Iterator
| cellIterator = nextRow.cellIterator(); // 逐个单元格遍历 | - Product aProduct = new Product(); // 创建Product对象aProduct,用于存储当前行数据对应的商品信息
- // 读取单元格填充aProduct
- while (cellIterator.hasNext()) {
- Cell nextCell = cellIterator.next();
- int columnIndex = nextCell.getColumnIndex(); //获取单元格的索引,即列号
- switch (columnIndex) {
- case 0:
- aProduct.setName((String) ExcelUtil.getCellValue(nextCell)); // 针对不同的列号执行相应的操作,将单元格数据填充到aProduct对象的相应属性中
- break;
- case 1:
- aProduct.setImage((String) ExcelUtil.getCellValue(nextCell));
- break;
- case 2:
- aProduct.setDetail((String) ExcelUtil.getCellValue(nextCell));
- break;
- case 3:
- Double cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
- aProduct.setCategoryId(cellValue.intValue());
- break;
- case 4:
- cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
- aProduct.setPrice(cellValue.intValue());
- break;
- case 5:
- cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
- aProduct.setStock(cellValue.intValue());
- break;
- case 6:
- cellValue = (Double) ExcelUtil.getCellValue(nextCell); // excel中数字类型默认为Double
- aProduct.setStatus(cellValue.intValue());
- break;
- default:
- break;
- }
- }
- listProducts.add(aProduct); // 将填充好数据的aProduct对象添加到商品列表listProducts中
- }
- workbook.close(); // 关闭Excel工作簿
- inputStream.close(); // 关闭文件输入流
- return listProducts;
- }
综上,实现了读取Excel中的数据,填充进入对象listProducts,最终添加到数据库的功能。