如何通过 XSL 返回外部 PDF 文件的(总)页数

Posted

技术标签:

【中文标题】如何通过 XSL 返回外部 PDF 文件的(总)页数【英文标题】:How to return the (total) pagecount of external PDF files via XSL 【发布时间】:2016-11-15 21:19:17 【问题描述】:

是否可以通过 XSL 返回外部 PDF 文件的总页数? AntennaHouse Formatter 是否有等效的扩展名?

提前致谢!

【问题讨论】:

我认为您可以使用预定义的 CSS counter(pages),但我目前不确定您将如何将它放入您的 XSLT。 【参考方案1】:

如果您使用基于 Java 且允许外部函数调用的 XSLT 处理器(例如 Saxon PE 或 EE),那么 Apache PDFBox 将为您提供帮助。

PDF 框: https://pdfbox.apache.org/

PDFBox 的 PDDocument 类具有返回目标 PDF 的页数的方法。因此,您可以通过以下步骤获取页数:

    编写 Java 类和静态方法。 从 XSLT styleshhet 调用它。

[Java 示例代码]

package com.acme.pdfutil;
import java.io.File;
import org.apache.pdfbox.pdmodel.PDDocument;
public class pdfDocument 
    /**
     * Get the page count of specified PDF file.
     * @param filePath 
     * @return Page count
     */
    public static int getPageCount(String filePath)
        File pdfFile = null;
        PDDocument pdfDoc = null;
        int pageCount = -1;
        try 
            pdfFile = new File(filePath);
            pdfDoc = PDDocument.load(pdfFile);
            pageCount = pdfDoc.getNumberOfPages();
        
        catch (Exception e) 
            System.out.println("[getPageCount] " + e.getMessage());
        
        finally 
            if (pdfDoc != null)
                try
                    pdfDoc.close();
                
                catch (Exception e) 
                    ;
                
            
        
        return pageCount;
    

[XSLT 样式表]

<xsl:stylesheet version="2.0" 
 xmlns:fo="http://www.w3.org/1999/XSL/Format" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:acmejava="java:com.acme.pdfutil.pdfDocument"
>
…
<!-- Call external function -->
<xsl:variable name=”pdfPageCount” as="xs:integer" select="acmejava:getPageCount($pdfPath)"/>
…

【讨论】:

您正在使用一种过时(而且过于复杂)的方法来打开 PDF 文件。正确的做法是PDDocument pdf = PDDocument.load(file); 谢谢。几年前,当 PDFBox 版本为 1.7(?)时,我编写了这段代码。所以我根据你的建议更正了它。【参考方案2】:

不是开箱即用的,不。方法包括:

使用可以报告页数的命令行工具,例如 pdftk (https://www.pdflabs.com/tools/pdftk-server/)。在运行 XSLT 以创建 FO 之前,您可以在 PDF 上运行该工具并将结果保存到文件中,然后您将在 XSLT 处理期间读取该文件。 不太可靠,您可以在 PDF 上使用grep 等,并将其输出保存到要读取的文件中。参见,例如,http://www.unix.com/printthread.php?t=55661&pp=40 如果您认为您的所有 PDF 都可以通过 XSLT 读取为“未解析的文本”,那么您可以使用 unparsed-text() 读取 PDF,然后使用 XSLT 的正则表达式功能来查找正确的字符串。 您可以在 XSLT 中使用 Print and Page Layout Community Group (https://www.w3.org/community/ppl/wiki/XSLTExtensions) 中的 XSLT 扩展,从仅包含外部 PDF 的 FO 文件中获取区域树并计算其中的页数。 在运行 XSLT 之前,您可以从 Antenna House(请参阅 https://www.antennahouse.com/antenna1/ahpdfxml-conversion-library/)运行 AHPDFXML 以获取 PDF 的 XML 表示,然后您的 XSLT 可以计算该 XML 中的页数。

【讨论】:

谢谢!您第一个提到的解决方案对我来说是可行的。我现在正在生成一个带有小型自定义 Java 类的附加 XML 文件。此 XML 包含 PDF 文件名和相应的页数。通过 XSL,我只是使用 document() 函数读取 XML 数据并可以访问数据。

以上是关于如何通过 XSL 返回外部 PDF 文件的(总)页数的主要内容,如果未能解决你的问题,请参考以下文章

如何在java中读取xep文件数据

如何在java中读取xep文件数据

如何使用 XSL 检查是不是存在外部文件?

在 XSL-FO 中使用外部 CSS

如何在 Java 中从 XML 创建 PDF?

如何为 xsl-fo 中的每个页面添加页眉和页脚以生成 pdf