You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中使用iText按正确顺序提取带格式的PDF文本?

结合iText文本顺序提取与格式信息捕获的实现方案

核心思路

要同时实现按视觉顺序提取文本和捕获字体格式信息,本质是把格式数据绑定到按视觉排序后的文本块上——前者解决文本乱序问题,后者解决格式提取问题,关键在于在遍历文本元素时同步记录位置与格式属性。

具体实现步骤

1. 搭建视觉顺序遍历的基础框架

沿用你提到的文本顺序提取方案,基于iText7的LocationTextExtractionStrategy扩展,通过自定义TextChunkLocationStrategy确保文本块按行、列的视觉顺序排列:

// 自定义文本块位置策略,适配你的PDF布局(比如多列、复杂排版)
TextChunkLocationStrategy visualLocationStrategy = new TextChunkLocationStrategy() {
    @Override
    public TextChunkLocation createLocation(RenderTextEvent renderEvent) {
        // 这里实现按视觉位置排序的逻辑,比如按Y坐标(行)降序、X坐标(列)升序
        return new DefaultTextChunkLocation(
            renderEvent.getFontSize(),
            renderEvent.getBaseline().getY(),
            renderEvent.getBaseline().getX(),
            renderEvent.getWidthOfSpace()
        );
    }
};

2. 扩展策略同步捕获格式信息

继承LocationTextExtractionStrategy,重写eventOccurred方法,在处理文本渲染事件时,同时记录字体名、大小、样式等属性:

public class FormattedVisualTextStrategy extends LocationTextExtractionStrategy {
    private List<FormattedTextChunk> formattedChunkList = new ArrayList<>();

    public FormattedVisualTextStrategy(TextChunkLocationStrategy locationStrategy) {
        super(locationStrategy);
    }

    @Override
    public void eventOccurred(IEventData data, EventType type) {
        if (type == EventType.RENDER_TEXT) {
            RenderTextEvent renderEvent = (RenderTextEvent) data;
            PdfFont font = renderEvent.getFont();
            FontProgram fontProgram = font.getFontProgram();
            
            // 提取格式信息
            String fontName = fontProgram.getFontNames().getFontName();
            float fontSize = renderEvent.getFontSize();
            boolean isBold = fontProgram.isBold();
            boolean isItalic = fontProgram.isItalic();

            // 创建带格式的文本块,绑定位置信息用于排序
            FormattedTextChunk chunk = new FormattedTextChunk(
                renderEvent.getText(),
                fontName,
                fontSize,
                isBold,
                isItalic,
                getLocationStrategy().createLocation(renderEvent)
            );
            formattedChunkList.add(chunk);
        } else {
            super.eventOccurred(data, type);
        }
    }

    // 获取排序后的带格式文本块列表
    public List<FormattedTextChunk> getSortedFormattedChunks() {
        formattedChunkList.sort((c1, c2) -> c1.getLocation().compareTo(c2.getLocation()));
        return formattedChunkList;
    }

    // 自定义带格式文本块实体类
    public static class FormattedTextChunk {
        private String text;
        private String fontName;
        private float fontSize;
        private boolean isBold;
        private boolean isItalic;
        private TextChunkLocation location;

        // 构造方法、getter/setter省略
    }
}

3. 生成最终的有序带格式文本

通过扩展后的策略处理PDF页面,获取排序后的带格式文本块,再按需拼接成结构化输出:

// 初始化PDF文档
PdfDocument pdfDoc = new PdfDocument(new PdfReader("target.pdf"));

for (int pageNum = 1; pageNum <= pdfDoc.getNumberOfPages(); pageNum++) {
    PdfPage page = pdfDoc.getPage(pageNum);
    FormattedVisualTextStrategy strategy = new FormattedVisualTextStrategy(visualLocationStrategy);
    PdfCanvasProcessor processor = new PdfCanvasProcessor(strategy);
    processor.processPageContent(page);

    // 获取排序后的带格式文本块
    List<FormattedVisualTextStrategy.FormattedTextChunk> sortedChunks = strategy.getSortedFormattedChunks();

    // 示例:生成Markdown格式的输出
    StringBuilder mdOutput = new StringBuilder();
    for (FormattedVisualTextStrategy.FormattedTextChunk chunk : sortedChunks) {
        String styledText = chunk.getText();
        if (chunk.isBold()) styledText = "**" + styledText + "**";
        if (chunk.isItalic()) styledText = "*" + styledText + "*";
        mdOutput.append(styledText);
    }
    System.out.println("第" + pageNum + "页输出:\n" + mdOutput);
}
pdfDoc.close();

关键注意事项

  • 字体样式检测:优先使用FontProgram.isBold()/isItalic()判断样式,比解析字体名更可靠,避免因字体名不规范导致的误判。
  • 文本块合并:同一行、同格式的相邻文本块可合并,减少细碎的格式标记,提升输出可读性。
  • 复杂布局适配:针对多列、浮动元素的PDF,需调整TextChunkLocationStrategy的排序逻辑,确保列内顺序正确,列间按视觉流向排序。

内容的提问来源于stack exchange,提问作者Ehsan Sharifi Esfahani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 03:51:39