0

我想用 iText7 移动文本。我有一个源边界框,它可以在页面上的某个位置,我有一个目标边界框,它有一个固定的位置(包括宽度和高度)。我会保持在同一页面上。源框和目标框可以重叠。源边界框也可以大于目标框。在这种情况下,我必须减小字体大小。文字应保留字体、颜色等。

iText 网站上有一个剪切和粘贴示例。但是在结果 pdf 文件中,您可以选择新旧位置的文本(仅使用普通的 pdf 阅读器尝试过)。我不希望在旧位置可以选择文本。

我想,也许我可以选择文本并将其放在新位置并将其从旧位置删除。对于后者,我需要 pdfSweep,但这没关系。在新位置添加文本应该没有问题。即使文本有不同的字体、大小等。iText 网站上有很多示例。我知道选择文本的唯一方法就像这个例子中所示。这给了我只有文字。但是要将其放置在具有相同字体、颜色等的目标位置,我也需要所有这些信息。我知道,那个 pdf 不是用来编辑的。这在 StackOverflow 上的答案中经常提到。有没有办法用 iText7 做到这一点?

4

1 回答 1

0

iText 中没有高级 API 允许您移动页面内容,特别是不是来自某个 rectangle 的所有内容。一个原因可能是,总的来说,这不仅仅是移动。PDF 通常包含影响较大区域的结构,并且这些结构不仅必须移动,而是复制,并且每个副本都限制在其区域内。

但是,确实有可能将 OP 找到的剪切和粘贴示例与 OP 已经考虑的 pdfSweep 模块结合到一个解决方案中,该解决方案可以防止在旧位置选择文本,例如:

public void moveCleanSection(PdfReader pdfReader, String targetFile, int page, Rectangle from, Rectangle to) throws IOException
{
    LicenseKey.loadLicenseFile("itextkey-multiple-products.xml");

    ByteArrayOutputStream interimMain = new ByteArrayOutputStream();
    ByteArrayOutputStream interimPage = new ByteArrayOutputStream();
    ByteArrayOutputStream interimSection = new ByteArrayOutputStream();

    try (   PdfDocument pdfMainDocument = new PdfDocument(pdfReader);
            PdfDocument pdfPageDocument = new PdfDocument(new PdfWriter(interimPage)) )
    {
        pdfMainDocument.setCloseReader(false);
        pdfMainDocument.copyPagesTo(page, page, pdfPageDocument);
    }

    try (   PdfDocument pdfMainDocument = new PdfDocument(pdfReader, new PdfWriter(interimMain));
            PdfDocument pdfSectionDocument = new PdfDocument(new PdfReader(new ByteArrayInputStream(interimPage.toByteArray())), 
            new PdfWriter(interimSection))  )
    {

        List<PdfCleanUpLocation> cleanUpLocations = new ArrayList<PdfCleanUpLocation>();
        cleanUpLocations.add(new PdfCleanUpLocation(page, from, null));
        cleanUpLocations.add(new PdfCleanUpLocation(page, to, null));

        PdfCleanUpTool cleaner = new PdfCleanUpTool(pdfMainDocument, cleanUpLocations);
        cleaner.cleanUp();

        cleanUpLocations = new ArrayList<PdfCleanUpLocation>();
        Rectangle mediaBox = pdfSectionDocument.getPage(1).getMediaBox();

        if (from.getTop() < mediaBox.getTop())
            cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(mediaBox.getLeft(), from.getTop(), mediaBox.getWidth(), mediaBox.getTop() - from.getTop()), null));
        if (from.getBottom() > mediaBox.getBottom())
            cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(mediaBox.getLeft(), mediaBox.getBottom(), mediaBox.getWidth(), from.getBottom() -  mediaBox.getBottom()), null));
        if (from.getLeft() > mediaBox.getLeft())
            cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(mediaBox.getLeft(), mediaBox.getBottom(), from.getLeft() - mediaBox.getLeft(), mediaBox.getHeight()), null));
        if (from.getRight() < mediaBox.getRight())
            cleanUpLocations.add(new PdfCleanUpLocation(1, new Rectangle(from.getRight(), mediaBox.getBottom(), mediaBox.getRight() - from.getRight(), mediaBox.getHeight()), null));

        cleaner = new PdfCleanUpTool(pdfSectionDocument, cleanUpLocations);
        cleaner.cleanUp();
    }

    try (   PdfDocument pdfSectionDocument = new PdfDocument(new PdfReader(new ByteArrayInputStream(interimSection.toByteArray())));
            PdfDocument pdfMainDocument = new PdfDocument(new PdfReader(new ByteArrayInputStream(interimMain.toByteArray())), new PdfWriter(targetFile)) )
    {
        float scale = Math.min(to.getHeight() / from.getHeight(), to.getWidth() / from.getWidth());
        pdfSectionDocument.getPage(1).setMediaBox(from);
        PdfFormXObject pageXObject = pdfSectionDocument.getFirstPage().copyAsFormXObject(pdfMainDocument);
        PdfPage pdfPage = pdfMainDocument.getPage(page);
        PdfCanvas pdfCanvas = new PdfCanvas(pdfPage);
        pdfCanvas.addXObject(pageXObject, scale, 0, 0, scale, (to.getLeft() - from.getLeft() * scale), (to.getBottom() - from.getBottom() * scale));
    }
}

(来自MoveSectionCleanly.java

注意:由于 pdfSweep 的性质,位于源区域边界上的文本会从源和副本中删除。

于 2016-11-15T07:33:22.020 回答