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

如何使用PDFBox提取PDF内容时保留单词间的多空格?

用PDFBox保留PDF原排版(多空格)的文本提取方法

默认PDFBox的文本提取会忽略字符的位置信息,直接按顺序拼接字符,导致原有的多空格排版丢失。要保留排版,需要通过跟踪字符的坐标位置,手动计算字符间的间距并填充空格。

实现步骤

  1. 自定义PDFTextStripper子类,重写writeString方法——这个方法可以获取到每个字符的精确位置坐标。
  2. 跟踪每行字符的X坐标,计算当前字符与前一个字符的水平间距,将间距转换为对应数量的空格。
  3. 处理换行逻辑,每行开始时重置位置跟踪。

示例代码(Java)

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.List;

public class LayoutPreservingTextStripper extends PDFTextStripper {
    private float lastX = -1;
    private static final float SPACE_PIXEL_WIDTH = 6; // 根据字体调整,默认按6像素对应一个空格

    public LayoutPreservingTextStripper() throws IOException {
        super();
    }

    @Override
    protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
        Writer writer = getWriter();
        if (writer == null) return;

        for (int i = 0; i < textPositions.size(); i++) {
            TextPosition pos = textPositions.get(i);
            float currentX = pos.getXDirAdj();

            // 不是行首,计算与前一个字符的间距,填充空格
            if (lastX != -1) {
                float gap = currentX - lastX - pos.getWidthDirAdj();
                if (gap > 1) { // 忽略极小间距
                    int spaces = (int) Math.round(gap / SPACE_PIXEL_WIDTH);
                    writer.write(" ".repeat(spaces));
                }
            }

            writer.write(pos.getUnicode());
            lastX = currentX + pos.getWidthDirAdj();
        }
    }

    @Override
    protected void writeLineSeparator() throws IOException {
        super.writeLineSeparator();
        lastX = -1; // 换行后重置X坐标跟踪
    }

    public static void main(String[] args) throws IOException {
        try (PDDocument document = PDDocument.load(new File("your-file.pdf"))) {
            LayoutPreservingTextStripper stripper = new LayoutPreservingTextStripper();
            String extractedText = stripper.getText(document);
            System.out.println(extractedText);
        }
    }
}

关键说明

  • SPACE_PIXEL_WIDTH:需要根据PDF中字体的实际空格宽度调整,比如如果原PDF的空格宽度是8像素,就改成8,确保填充的空格和原排版匹配。
  • 代码通过TextPosition获取每个字符的X坐标和宽度,计算字符间的空白间距,转换为对应数量的空格填充。
  • 换行时重置lastX,避免跨行计算间距。

效果

使用这个自定义提取器后,提取出的文本会保留原PDF中的多空格排版,接近你期望的输出格式。

内容的提问来源于stack exchange,提问作者iiprateek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 12:42:13