文章目录
一、接口定义与作用
- SheetContentsHandler 是 Apache POI 库中用于高效读取和处理大型 Excel 工作表的一种接口。
- SheetContentsHandler 是一个用户自定义实现的接口,位于 org.apache.poi.ss.usermodel 包下。其主要作用是定义如何处理从 Excel 工作表中逐行、逐单元格读取的数据。当你需要处理非常大的 Excel 文件,或者关注性能优化,避免一次性加载整个工作簿到内存时,可以采用基于事件的模型,即使用 SheetContentsHandler 接口。
public interface SheetContentsHandler {
void startRow(int rowNum);
void endRow(int rowNum);
void cell(String cellReference, String formattedValue, XSSFComment comment);
void headerFooter(String text, boolean isHeader, String tagName);
}
二、方法说明
startRow
- startRow(int rowNum): 当解析器开始处理新一行时调用。传入的 rowNum 参数表示当前行号。在此方法中,你可以初始化行相关的变量或状态。
endRow
- endRow(int rowNum): 在解析完一行的所有单元格后调用。同样提供 rowNum 表示刚刚结束的行号。你可以在此处进行行级的数据处理或聚合操作。
cell
- cell(String cellReference, String formattedValue, XSSFComment comment): 每当遇到一个单元格时调用。参数包括(下面3个)
- cellReference: 单元格的 A1 样式引用(如 “B3”),可用于确定单元格的位置。
- formattedValue: 单元格的已格式化值,即显示在 Excel 中的文本。注意,这可能不同于单元格的实际数值,特别是对于日期、数字等类型。
- comment: 如果该单元格有注释(评论),则传递 XSSFComment 对象;否则为 null。你可以在这里处理单元格数据和关联的注释。
headerFooter
- headerFooter(String text, boolean isHeader, String tagName): 当解析到页眉或页脚信息时调用。参数包括(下面3个)
- text: 页眉或页脚的文本内容。
- isHeader: 标志是否为页眉(true)或页脚(false)。
- tagName: 页眉或页脚的标签名称,如 “oddHeader” 或 “evenFooter”,用于区分奇偶页或不同区域的页眉页脚。
三、使用步骤
1、实现 SheetContentsHandler 接口
- 创建一个新的类,实现 SheetContentsHandler 接口,并根据实际需求实现上述方法。例如,你可以创建一个 MySheetHandler 类
public class MySheetHandler implements SheetContentsHandler {
// 实现接口方法
@Override
public void startRow(int rowNum) {
System.out.println("Starting row: " + rowNum);
// ... 初始化行相关变量或状态
}
@Override
public void endRow(int rowNum) {
System.out.println("Ending row: " + rowNum);
// ... 进行行级数据处理或聚合操作
}
@Override
public void cell(String cellReference, String formattedValue, XSSFComment comment) {
System.out.printf("Cell %s: %s (Comment: %s)\n", cellReference, formattedValue, comment != null ? comment.getString().getString() : "None");
// ... 处理单元格数据和注释
}
@Override
public void headerFooter(String text, boolean isHeader, String tagName) {
System.out.printf("%s: %s\n", isHeader ? "Header" : "Footer", text);
// ... 处理页眉或页脚信息
}
}
2、创建 SXSSFWorkbook 或 XSSFWorkbook 并设置 SheetContentsHandler
- 使用 SXSSFWorkbook 或 XSSFWorkbook 类(取决于你处理的是 .xlsx 还是 .xls 文件)来读取 Excel 文件。然后,创建一个 EventBasedExcelExtractor 或 XSSFEventBasedExcelExtractor 实例,并设置自定义的 SheetContentsHandler。
// 以 .xlsx 文件为例
SXSSFWorkbook workbook = new SXSSFWorkbook(new FileInputStream("path_to_your_file.xlsx"));
Sheet sheet = workbook.getSheetAt(0);
// 创建事件提取器并设置自定义 SheetContentsHandler
XSSFEventBasedExcelExtractor extractor = new XSSFEventBasedExcelExtractor(workbook);
extractor.setSheetContentsHandler(new MySheetHandler());
// 提取工作表内容
extractor.getText();
四、注意事项
-
事件驱动处理: 使用 SheetContentsHandler 时,数据是按事件(行开始、单元格、行结束等)顺序依次传递给你的处理器。这意味着你必须在处理器内部保持必要的状态,以便正确处理这些事件。
-
资源管理: 由于 SheetContentsHandler 是为了处理大文件而设计的,因此务必确保在完成处理后正确关闭所有资源,如关闭输入流、释放工作簿对象等,以防止资源泄漏。
-
性能与内存占用: 采用 SheetContentsHandler 可显著降低内存消耗,尤其适合处理包含大量数据的工作表。但请注意,虽然事件驱动模型减少了内存压力,但它可能不如直接使用 POI 的模型(如 XSSFRow、XSSFCell 等)那么直观和易于编程。
五、总结
- SheetContentsHandler 是 Apache POI 提供的一种低内存开销、事件驱动的方式来处理 Excel 工作表内容。通过实现该接口并设置到相应的提取器中,你可以定制化地处理工作表中的每一行、每一单元格以及页眉页脚信息,特别适用于对大文件进行高效读取和分析的场景。