MIT License

项目介绍

rostrovsky/pdf-table 是一个托管在 GitHub 上的开源项目,主要使用 Java 编写,采用 MIT License 许可证,目前获得 82 个 Star、13 次 Fork。

仓库全名
rostrovsky/pdf-table
开源许可证
MIT License
Star 数
82
Fork 数
13
未关闭 Issue
2

README 摘要

= PDF-table :toc: == What is PDF-table? PDF-table is Java utility library that can be used for parsing tabular data in PDF documents. + Core processing of PDF documents is performed with utilization of Apache PDFBox and OpenCV. == Prerequisites === JDK JAVA 8 is required. === External dependencies pdf-table requires compiled OpenCV 3.4.2 to work properly: . Download OpenCV v3.4.2 from…

完整内容见 GitHub 原始 README 或本页 。

常见问题

pdf-table 用什么语言开发?

主要使用 Java 编写,采用 MIT License 许可证,目前有 82 个 Star。

pdf-table 可以免费商用吗?

仓库采用 MIT License 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 pdf-table 的源码?

可以直接克隆仓库:git clone https://github.com/rostrovsky/pdf-table.git,默认分支为 master;安装与运行步骤见仓库 README。

pdf-table 最近还在维护吗?

仓库最近一次更新为 2023年5月10日,当前有 2 个未关闭 Issue;Star 数为 82,可作为社区活跃度的参考。

关于

GitHub 原始描述(英文)

Java utility for parsing PDF tabular data using Apache PDFBox and OpenCV

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
115
价值分
53
活跃状态
活跃

语言占比

Java

Release

README

= PDF-table :toc:

== What is PDF-table? PDF-table is Java utility library that can be used for parsing tabular data in PDF documents. + Core processing of PDF documents is performed with utilization of Apache PDFBox and OpenCV.

== Prerequisites

=== JDK

JAVA 8 is required.

=== External dependencies

pdf-table requires compiled OpenCV 3.4.2 to work properly:

. Download OpenCV v3.4.2 from https://github.com/opencv/opencv/releases/tag/3.4.2 . Unpack it and add to your system PATH: * Windows: <opencv dir>\build\java\x64 * Linux: TODO

== Installation [source, xml]

com.github.rostrovsky pdf-table 1.0.0 ----

== Usage

=== Parsing PDFs When PDF document page is being parsed, following operations are performed:

. Page is converted to grayscale image [OpenCV]. . Binary Inverted Threshold (BIT) is applied to grayscaled image [OpenCV]. . Contours are detected on BIT image and contour mask is created (additional Canny filtering can be turned on in this step) [OpenCV]. . Contour mask is XORed with BIT image [OpenCV]. . Contours are detected once again on XORed image (additional Canny filtering can be turned on in this step) [OpenCV]. . Final contours are drawn [OpenCV]. . Bounding rectangles are detected from final contours [OpenCV]. . PDF is being parsed region-by-region using bounding rectangles coordinates [Apache PDFBox].

Above algorithm is mostly derived from http://stackoverflow.com/a/23106594.

For more information about parsed output, refer to <>

==== single-threaded example [source, java]

class SingleThreadParser { public static void main(String[] args) throws IOException { PDDocument pdfDoc = PDDocument.load(new File(“some.pdf”)); PdfTableReader reader = new PdfTableReader(); List parsed = reader.parsePdfTablePages(pdfDoc, 1, pdfDoc.getNumberOfPages()); } }

==== multi-threaded example [source, java]

class MultiThreadParser { public static void main(String[] args) throws IOException { final int THREAD_COUNT = 8; PDDocument pdfDoc = PDDocument.load(new File(“some.pdf”)); PdfTableReader reader = new PdfTableReader();

    // parse pages simultaneously
    ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
    List<Future<ParsedTablePage>> futures = new ArrayList<>();
    for (final int pageNum : IntStream.rangeClosed(1, pdfDoc.getNumberOfPages()).toArray()) {
        Callable<ParsedTablePage> callable = () -> {
            ParsedTablePage page = reader.parsePdfTablePage(pdfDoc, pageNum);
            return page;
        };
        futures.add(executor.submit(callable));
    }

    // collect parsed pages
    List<ParsedTablePage> unsortedParsedPages = new ArrayList<>(pdfDoc.getNumberOfPages());
    try {
        for (Future<ParsedTablePage> f : futures) {
            ParsedTablePage page = f.get();
            unsortedParsedPages.add(page.getPageNum() - 1, page);
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

    // sort pages by pageNum
    List<ParsedTablePage> sortedParsedPages = unsortedParsedPages.stream()
            .sorted((p1, p2) -> Integer.compare(p1.getPageNum(), p2.getPageNum())).collect(Collectors.toList());
}

}

=== Saving PDF pages as PNG images PDF-Table provides methods for saving PDF pages as PNG images. + Rendering DPI can be modified in PdfTableSettings (see: <>).

==== single-threaded example [source, java]

class SingleThreadPNGDump { public static void main(String[] args) throws IOException { PDDocument pdfDoc = PDDocument.load(new File(“some.pdf”)); Path outputPath = Paths.get(“C:”, “some_directory”); PdfTableReader reader = new PdfTableReader(); reader.savePdfPagesAsPNG(pdfDoc, 1, pdfDoc.getNumberOfPages(), outputPath); } }

==== multi-threaded example [source, java]

class MultiThreadPNGDump { public static void main(String[] args) throws IOException { final int THREAD_COUNT = 8; Path outputPath = Paths.get(“C:”, “some_directory”); PDDocument pdfDoc = PDDocument.load(new File(“some.pdf”)); PdfTableReader reader = new PdfTableReader();

    ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
    List<Future<Boolean>> futures = new ArrayList<>();
    for (final int pageNum : IntStream.rangeClosed(1, pdfDoc.getNumberOfPages()).toArray()) {
        Callable<Boolean> callable = () -> {
            reader.savePdfPageAsPNG(pdfDoc, pageNum, outputPath);
            return true;
        };
        futures.add(executor.submit(callable));
    }

    try {
        for (Future<Boolean> f : futures) {
            f.get();
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

}

=== Saving debug PNG images When tables in PDF document cannot be parsed correctly with default settings, user can save debug images that show page at various stages of processing. + Using these images, user can adjust PdfTableSettings accordingly to achieve desired results (see: <>).

==== single-threaded example [source, java]

class SingleThreadDebugImgsDump { public static void main(String[] args) throws IOException { PDDocument pdfDoc = PDDocument.load(new File(“some.pdf”)); Path outputPath = Paths.get(“C:”, “some_directory”); PdfTableReader reader = new PdfTableReader(); reader.savePdfTablePagesDebugImages(pdfDoc, 1, pdfDoc.getNumberOfPages(), outputPath); } }

==== multi-threaded example [source, java]

class MultiThreadDebugImgsDump { public static void main(String[] args) throws IOException { final int THREAD_COUNT = 8; Path outputPath = Paths.get(“C:”, “some_directory”); PDDocument pdfDoc = PDDocument.load(new File(“some.pdf”)); PdfTableReader reader = new PdfTableReader();

    ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
    List<Future<Boolean>> futures = new ArrayList<>();
    for (final int pageNum : IntStream.rangeClosed(1, pdfDoc.getNumberOfPages()).toArray()) {
        Callable<Boolean> callable = () -> {
            reader.savePdfTablePagesDebugImage(pdfDoc, pageNum, outputPath);
            return true;
        };
        futures.add(executor.submit(callable));
    }

    try {
        for (Future<Boolean> f : futures) {
            f.get();
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

}

=== Parsing settings

PDF rendering and OpenCV filtering settings are stored in PdfTableSettings object.

Custom settings instance can be passed to PdfTableReader constructor when non-default values are needed:

[source, java]

(…)

// build settings object PdfTableSettings settings = PdfTableSettings.getBuilder() .setCannyFiltering(true) .setCannyApertureSize(5) .setCannyThreshold1(40) .setCannyThreshold2(190.5) .setPdfRenderingDpi(160) .build();

// pass settings to reader PdfTableReader reader = new PdfTableReader(settings);

=== Output format Each parsed PDF page is being returned as ParsedTablePage object: [source, java]

(…)

PDDocument pdfDoc = PDDocument.load(new File(“some.pdf”)); PdfTableReader reader = new PdfTableReader();

// first page in document has index == 1, not 0 ! ParsedTablePage firstPage = reader.parsePdfTablePage(pdfDoc, 1);

// getting page number assert firstPage.getPageNum() == 1;

// rows and cells are zero-indexed just like elements of the List // getting first row ParsedTablePage.ParsedTableRow firstRow = firstPage.getRow(0);

// getting third cell in second row String thirdCellContent = firstPage.getRow(1).getCell(2);

评论

暂无评论