如何使用 Apache POI 将文本水印添加到 80MB 的现有 Excel 文件中?

问题描述 投票:0回答:1

我正在开发一个 Java 项目,该项目涉及使用 Apache POI 将文本水印添加到大型现有 Excel 文件(.xlsx、.xls)。

我正在处理的文件大小通常约为 80MB。

我尝试了几种不同的方法,但遇到了性能问题(例如 OOM)。

使用 Apache POI 向大型 Excel 文件添加水印时,我应该注意哪些最佳实践?

如有任何建议,我们将不胜感激!!!

java excel apache-poi
1个回答
0
投票

第一种方法,您可以尝试增加分配的堆大小,看看是否可以解决您的问题,否则您可以尝试下面的解决方案:

也许您在以流方式处理文件时缺少的是使用此行添加要在内存中保留多少行的参数。 (在下面的示例中为 100)。

这里:

SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(xssfWorkbook, 100);

至于建议的解决方案,您可以尝试这样的方法:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFTextBox;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ExcelWatermark {

    public static void main(String[] args) throws IOException {
        String inputFilePath = "path/to/large/excel/file.xlsx";
        String outputFilePath = "path/to/output/excel/file_with_watermark.xlsx";
        String watermarkText = "CONFIDENTIAL";

        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XSSFWorkbook workbook = new XSSFWorkbook(fis);
             SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(workbook, 100)) {

            for (int i = 0; i < sxssfWorkbook.getNumberOfSheets(); i++) {
                XSSFSheet sheet = (XSSFSheet) sxssfWorkbook.getSheetAt(i);
                addWatermarkToSheet(sheet, watermarkText);
            }

            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
                sxssfWorkbook.write(fos);
            }
        }
    }

    private static void addWatermarkToSheet(XSSFSheet sheet, String watermarkText) {
        //Example of watermark feel free to put yours.
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        XSSFTextBox textBox = drawing.createTextbox(new XSSFClientAnchor());
        textBox.setText(watermarkText);
        textBox.setFillColor(200, 200, 200); // Light gray background
        textBox.setLineStyleColor(200, 200, 200); // Light gray border
        textBox.setNoFill(false);
        textBox.setAnchor(new XSSFClientAnchor(0, 0, 255, 255, 0, 0, 10, 10));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.