PdfBox - 如何从文本加载颜色

PdfBox - How to load color from text

我在很多不同的论坛上看到过这个问题,但我还没有看到它得到正确的回答。有一些可能对某些人有用,但它们太复杂了。我自己找到了解决方案,所以如果您有兴趣找到解决方案,请查看答案。

答案:您通过 PDFTextStripper 中的 processTextPosition() 方法提取每个字符的颜色 class。

对于要提取的颜色,需要覆盖 PDFTextStripper 中的构造函数,以便它有更多的运算符来从文本中提取颜色,因为这最初不是默认 PDFTextStripper 中的功能。查看文本提取下的 https://pdfbox.apache.org/2.0/migration.html 了解更多信息。从那个 link,我们找到要添加到 PDFTextStripper 的重写构造函数的运算符:

addOperator(new SetStrokingColorSpace());
addOperator(new SetNonStrokingColorSpace());
addOperator(new SetStrokingDeviceCMYKColor());
addOperator(new SetNonStrokingDeviceCMYKColor());
addOperator(new SetNonStrokingDeviceRGBColor());
addOperator(new SetStrokingDeviceRGBColor());
addOperator(new SetNonStrokingDeviceGrayColor());
addOperator(new SetStrokingDeviceGrayColor());
addOperator(new SetStrokingColor());
addOperator(new SetStrokingColorN());
addOperator(new SetNonStrokingColor());
addOperator(new SetNonStrokingColorN());

然后我们可以向我们的新子添加一个布尔值class,每次在处理文本时开始一个新行时它都会被设置为真:

public class PDFTextStripperSuper extends PDFTextStripper {
    boolean newLine = true;
    
    public PDFTextStripperSuper() throws IOException {
        addOperator(new SetStrokingColorSpace());
        addOperator(new SetNonStrokingColorSpace());
        addOperator(new SetStrokingDeviceCMYKColor());
        addOperator(new SetNonStrokingDeviceCMYKColor());
        addOperator(new SetNonStrokingDeviceRGBColor());
        addOperator(new SetStrokingDeviceRGBColor());
        addOperator(new SetNonStrokingDeviceGrayColor());
        addOperator(new SetStrokingDeviceGrayColor());
        addOperator(new SetStrokingColor());
        addOperator(new SetStrokingColorN());
        addOperator(new SetNonStrokingColor());
        addOperator(new SetNonStrokingColorN());
    }
    
    @Override
    protected void startPage(PDPage page) throws IOException {
        newLine = true;
        super.startPage(page);
    }

    @Override
    protected void writeLineSeparator() throws IOException {
        newLine = true;
        super.writeLineSeparator();
    }
}

现在我们有了一个文本处理器,可以提取每一行文本以及字符颜色。要实现这一点,我们要做的就是覆盖 writeString() 方法来获取每一行文本,以及覆盖 processTextPosition() 方法来获取每个字符的颜色:

public class DocAnalyzer {
    public DocAnalyzer(PDDocument doc) throws IOException {
        ArrayList<String> lines = new ArrayList<>();
        ArrayList<PDColor> charColors = new ArrayList<>();
        PDFTextStripperSuper tp = new PDFTextStripperSuper() {
            @Override
            protected void writeString(String text, List<TextPosition> textPositions)
                    throws IOException {
                if (newLine) {
                    lines.add(text);
                    newLine = false;
                }
                super.writeString(text, textPositions);
            }
            
            @Override
            protected void processTextPosition(TextPosition text) {
                super.processTextPosition(text);
                charColors.add(getGraphicsState().getNonStrokingColor());
            }
        };
        
        tp.getText(doc);//processes the text and adds to our lists
    }
}

给你!文本的所有颜色都应该在您的 charColors 列表中。这就是我给你的所有帮助 ;)!