当前位置: 首页 > 面试题库 >

使用PDFBox复制pdf是否可以像使用iText一样小?

司空朝
2023-03-14
问题内容

我正在阅读PDF并输出其中包含原始PDF的多个副本的PDF。我通过对PDFBox和iText做同样的事情来进行测试。如果我分别复制每个页面,iText会创建一个较小的输出。

问题: 在PDFBox中还有另一种方法可以使输出的PDF变小。

对于一个示例输入文件,使用两个工具生成两个副本到输出:

  • 原始PDF大小:30K
  • PDFBox(v 1.7.1)生成的PDF:84K
  • iText(v 5.3.4)生成的PDF:35K

PDFBox的Java代码(很抱歉给您造成错误处理)。请注意,它是如何反复读取输入并将其整体复制的:

PDFMergerUtility merger = new PDFMergerUtility();
PDDocument workplace = null;
try {
    for (int cnt = 0; cnt < COPIES; ++cnt) {
        PDDocument document = null;
        InputStream stream = null;
        try {
            stream = new FileInputStream(new File(sourceFileName));
            document = PDDocument.load(stream);
            if (workplace == null) {
                workplace = document;
            } else {
                merger.appendDocument(workplace, document);
            }
        } finally {
            if (document != null && document != workplace) {
                document.close();
            }
            if (stream != null) {
                stream.close();
            }
        }
    }

    OutputStream out = null;
    try {
        out = new FileOutputStream(new File(destinationFileName));
        workplace.save(out);
    } finally {
        if (out != null) {
            out.close();
        }
    }
} catch (COSVisitorException e1) {
    e1.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (workplace != null) {
        try {
            workplace.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

使用iText进行编码的代码。请注意,它是如何逐页加载输入文件并将每页传输到输出的:

Document document = null;
PdfReader reader = null;
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {
    inputStream = new FileInputStream(new File(sourceFileName));
    outputStream = new FileOutputStream(new File(destinationFileName));
    document = new Document();
    PdfCopy copy = new PdfSmartCopy(document, outputStream);
    document.open();
    reader = new PdfReader(inputStream);
    // loop over the pages in that document
    int pdfPageNo = reader.getNumberOfPages();
    for (int page = 0; page < pdfPageNo;) {
        PdfImportedPage onePage = copy.getImportedPage(reader, ++page);
        // duplicate each page N times
        for (int i = 0; i < COPIES; ++i) {
            copy.addPage(onePage);
        }
    }
    copy.freeReader(reader);
} catch (DocumentException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (reader != null) {
        reader.close();
    }
    if (document != null) {
        document.close();
    }
    try {
        if (inputStream != null) {
            inputStream.close();
        }
        if (outputStream != null) {
            outputStream.close();
        }
    } catch (IOException e) {
        // do nothing
    }
}

两者都被这个包围:

public class Duplicate {

    /** The original PDF file */
    private static final String sourceFileName = "PDF_CI_US2CA.pdf";

    /** The resulting PDF file. */
    private static final String destinationFileName = "itext_output.pdf";
    private static final int COPIES = 2;

    public static void main(String[] args) {
            ...
        }
}

问题答案:

使用以下解决方案,我能够创建具有许多重复页面的PDF文件,并且对存储的影响最小。

PDDocument samplePdf = null;
try {
    samplePdf = PDDocument.load(PDF_PATH);
    PDPage page = (PDPage) samplePdf.getDocumentCatalog().getAllPages().get(0);

    for(int i = 0; i < COPIES; i++) {
        samplePdf.importPage(page);
    }

    samplePdf.save(SAVE_PATH); //$NON-NLS-1$

} catch (IOException e) {
    e.printStackTrace();
} catch (COSVisitorException e) {
    e.printStackTrace();
}

在我的第一次尝试中,我使用了samplePdf.addPage(page)它,但是没有按预期工作。因此,显然,addimport功能之间存在差异。我必须检查源代码或文档以了解原因。无论如何,这应该可以帮助您使用PDFBox设计解决方案。



 类似资料:
  • 我正在阅读在一个PDF和输出一个PDF与多个副本的原始PDF在其中。我通过对PDFBox和iText执行相同的操作来进行测试。如果我单独复制每个页面,iText会创建一个小得多的输出。 对于一个输入文件示例,使用两种工具生成输出的两个副本: 原始PDF大小:30K PDFBox(v1.7.1)生成的PDF:84k iText(v 5.3.4)生成的PDF:35k PDFBox的Java代码(很抱歉

  • 背景 目前,我有一个解决方案,我在PDF中循环并在其中绘制黑色矩形。 所以我已经有了一个PDRectangle列表,它代表了我需要在pdf上填充/覆盖的正确区域,隐藏了我想要的所有文本。 问题所在 问题1:黑色矩形下方的文本很容易被复制、搜索或通过其他工具提取。 我通过展平我的pdf来解决这个问题(将其转换为图像,使其成为单层文档,黑色矩形不再被欺骗)。与此处描述的解决方案相同:使用pdfBox禁

  • 通常我会在返回特定对象的方法中实现switch case。如下所示: 现在我想知道是否有可能为价值分配目的编写一个开关案例?像下面这样: 当然,它可以通过简单的If-Else语句来实现,这个问题对我来说是为了理解switch case的更多功能 当然,在测试之后,我收到了错误消息

  • 问题内容: 我们需要将现有的多个PDF导入到一个新的PDF中。部分代码的工作方式类似于 iText in Action 2nd Edition 第6.2.1节中的示例代码: 但是,我们只是意识到在处理带有注解的可填充PDF(在我们的示例中,那些PDF已经填充了数据)时,所有填充数据都会丢失在新PDF中。 我们在本书的同一部分找到了答案: 重要的是要理解呈现页面内容所需的资源与页面的交互功能之间的区

  • 我们需要将现有的多个 PDF 导入到单个新 PDF 中。部分代码的工作方式类似于 iText 在操作 2nd 版的第 6.2.1 节中的示例代码: 然而,我们刚刚意识到,在处理带注释的可填充PDF时(在我们的例子中,那些PDF已经填充了数据),所有填充的数据在新的PDF中都丢失了。 我们在书的同一部分找到了答案: 了解呈现页面内容所需的资源与页面的交互功能之间的区别非常重要。通常,这些功能称为批注

  • 我想用ApachePDFBox在PDF上绘制一个矢量图像。 这是我用来绘制普通图像的代码 如果我使用或图像而不是png,则生成的PDF文档会损坏。 我希望图像是矢量图像的主要原因是,使用PNG或JPG时,图像看起来很糟糕,我认为它会被压缩,所以看起来很糟糕。对于矢量图像,这不应该发生(当我在Inkscape中将svg路径导出为PDF时,它不会发生,矢量路径会被保留)。 有没有办法使用Apache