杰瑞科技汇

Java如何读取Excel2007文件?

Java 读取 Excel 2007 文件

在 Java 中读取 Excel 2007 (.xlsx) 文件,可以使用 Apache POI 库,以下是详细的实现方法:

Java如何读取Excel2007文件?-图1
(图片来源网络,侵删)

添加依赖

确保你的项目中包含 Apache POI 的依赖,如果你使用 Maven,添加以下依赖到 pom.xml:

<dependencies>
    <!-- Apache POI for Excel 2007+ -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>
</dependencies>

基本读取代码示例

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class ExcelReader {
    public static void main(String[] args) {
        String filePath = "path/to/your/file.xlsx";
        try (FileInputStream fis = new FileInputStream(filePath);
             Workbook workbook = new XSSFWorkbook(fis)) {
            // 获取第一个工作表
            Sheet sheet = workbook.getSheetAt(0);
            // 遍历每一行
            for (Row row : sheet) {
                // 遍历每一列
                for (Cell cell : row) {
                    // 根据单元格类型获取值
                    switch (cell.getCellType()) {
                        case STRING:
                            System.out.print(cell.getStringCellValue() + "\t");
                            break;
                        case NUMERIC:
                            if (DateUtil.isCellDateFormatted(cell)) {
                                System.out.print(cell.getDateCellValue() + "\t");
                            } else {
                                System.out.print(cell.getNumericCellValue() + "\t");
                            }
                            break;
                        case BOOLEAN:
                            System.out.print(cell.getBooleanCellValue() + "\t");
                            break;
                        case FORMULA:
                            System.out.print(cell.getCellFormula() + "\t");
                            break;
                        default:
                            System.out.print("\t");
                    }
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

更实用的封装方法

以下是一个更实用的方法,可以将 Excel 数据读取为二维列表:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class ExcelReaderUtil {
    public static List<List<Object>> readExcel(String filePath) throws IOException {
        List<List<Object>> data = new ArrayList<>();
        try (FileInputStream fis = new FileInputStream(filePath);
             Workbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                List<Object> rowData = new ArrayList<>();
                for (Cell cell : row) {
                    rowData.add(getCellValue(cell));
                }
                data.add(rowData);
            }
        }
        return data;
    }
    private static Object getCellValue(Cell cell) {
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue();
                } else {
                    return cell.getNumericCellValue();
                }
            case BOOLEAN:
                return cell.getBooleanCellValue();
            case FORMULA:
                return cell.getCellFormula();
            case BLANK:
                return null;
            default:
                return null;
        }
    }
    public static void main(String[] args) {
        try {
            List<List<Object>> excelData = ExcelReaderUtil.readExcel("example.xlsx");
            // 打印数据
            for (List<Object> row : excelData) {
                for (Object cell : row) {
                    System.out.print(cell + "\t");
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

处理大文件(使用 SAX 模式)

对于非常大的 Excel 文件,可以使用 SAX 模式(事件驱动)来节省内存:

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFReader.SheetIterator;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class LargeExcelReader {
    public static void main(String[] args) throws IOException, InvalidFormatException {
        String filePath = "large_file.xlsx";
        try (FileInputStream fis = new FileInputStream(filePath)) {
            XSSFReader reader = new XSSFReader(fis);
            SharedStringsTable sst = reader.getSharedStringsTable();
            XMLReader parser = XMLReaderFactory.createXMLReader();
            parser.setContentHandler(new SheetHandler(sst));
            SheetIterator sheets = (SheetIterator) reader.getSheetsData();
            while (sheets.hasNext()) {
                InputStream sheet = sheets.next();
                InputSource sheetSource = new InputSource(sheet);
                parser.parse(sheetSource);
                sheet.close();
            }
        }
    }
    private static class SheetHandler extends DefaultHandler {
        private SharedStringsTable sst;
        private String cellContents;
        private boolean nextIsString;
        private List<List<String>> sheetData = new ArrayList<>();
        private List<String> currentRow = new ArrayList<>();
        public SheetHandler(SharedStringsTable sst) {
            this.sst = sst;
        }
        @Override
        public void startElement(String uri, String localName, String name, Attributes attributes) {
            if (name.equals("c")) {
                String cellType = attributes.getValue("t");
                if (cellType != null && cellType.equals("s")) {
                    nextIsString = true;
                } else {
                    nextIsString = false;
                }
                cellContents = "";
            }
        }
        @Override
        public void characters(char[] ch, int start, int length) {
            cellContents += new String(ch, start, length);
        }
        @Override
        public void endElement(String uri, String localName, String name) {
            if (name.equals("v")) {
                if (nextIsString) {
                    int idx = Integer.parseInt(cellContents);
                    currentRow.add(new XSSFRichTextString(sst.getItemAt(idx)).getString());
                } else {
                    currentRow.add(cellContents);
                }
            } else if (name.equals("row")) {
                sheetData.add(currentRow);
                currentRow = new ArrayList<>();
            }
        }
    }
}

注意事项

  1. 内存管理:对于大文件,考虑使用 SAX 模式或分块读取
  2. 错误处理:添加适当的异常处理
  3. 性能:频繁的文件 I/O 操作会影响性能,考虑缓存或批量处理
  4. 日期格式:Excel 中的日期可能需要特殊处理
  5. 公式计算:如果需要读取公式的计算结果,可以使用 FormulaEvaluator

代码提供了从简单到复杂的多种读取 Excel 2007 文件的方法,你可以根据实际需求选择合适的实现方式。

Java如何读取Excel2007文件?-图2
(图片来源网络,侵删)
Java如何读取Excel2007文件?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇