itext 或 itextsharp - 移动现有 PDF 中的文本

itext or itextsharp - move text in an existing PDF

我的目标是在某个矩形区域内移动 PDF 中的文本。 Whosebug 上有一个现有的项目,它已经让我接近实现这个目标: iText or iTextSharp rudimentary text edit

但是,我会回到在非常基本的水平上操作 PDF。是否有机会使用更高级别的 itext 工具来更改文本的位置?恐怕没有简单的解决办法,但我很乐意得到一些建议。

PS:另外请记住,我只想在矩形区域内移动文本,即与原始 PDF 中的区域匹配的文本(块)应该在其 x 和 y 坐标中移动一些.我对 PDF 的创建方式没有影响,我可以接受只能模糊地工作的解决方案。

我以为我理解了你的问题,但你对我的反问题的回答令人困惑,所以让我举一个例子来回答你的问题。

假设你有这样一段文字:

我还有一个矩形的坐标:new Rectangle(100, 500, 200, 600); 和一个偏移量:将该矩形中的所有内容向左移动 10 点,向底部移动 2 点,如下所示:

这很容易实现。看一下 CutAndPaste 示例:

public void manipulatePdf(String src, String dest)
    throws IOException, DocumentException {
    // Creating a reader
    PdfReader reader = new PdfReader(src);
    // step 1
    Rectangle pageSize = reader.getPageSize(1);
    Rectangle toMove = new Rectangle(100, 500, 200, 600);
    Document document = new Document(pageSize);
    // step 2
    PdfWriter writer
        = PdfWriter.getInstance(document, new FileOutputStream(dest));
    // step 3
    document.open();
    // step 4
    PdfImportedPage page = writer.getImportedPage(reader, 1);
    PdfContentByte cb = writer.getDirectContent();
    PdfTemplate template1 = cb.createTemplate(pageSize.getWidth(), pageSize.getHeight());
    template1.rectangle(0, 0, pageSize.getWidth(), pageSize.getHeight());
    template1.rectangle(toMove.getLeft(), toMove.getBottom(),
            toMove.getWidth(), toMove.getHeight());
    template1.eoClip();
    template1.newPath();
    template1.addTemplate(page, 0, 0);
    PdfTemplate template2 = cb.createTemplate(pageSize.getWidth(), pageSize.getHeight());
    template2.rectangle(toMove.getLeft(), toMove.getBottom(),
            toMove.getWidth(), toMove.getHeight());
    template2.clip();
    template2.newPath();
    template2.addTemplate(page, 0, 0);
    cb.addTemplate(template1, 0, 0);
    cb.addTemplate(template2, -20, -2);
    // step 4
    document.close();
    reader.close();
}

如果这不是您想要的。如果您想检测实际单词并移动这些单词,那么您就有问题了。在那种情况下,我们谈论的是一个很容易花费几个月的工作才能正确完成的项目,而你的简短问题在很大程度上不足以知道在可以想象的许多边缘情况下该怎么做。

与上面相同的代码,但在 C# 中,带有命名空间:

        // Creating a reader
        iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(src);

        // step 1
        Rectangle pageSize = reader.GetPageSize(1);
        Rectangle toMove = new Rectangle(100, 500, 200, 600);
        Document document = new Document(pageSize);

        // step 2
        iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, new FileStream(dest, FileMode.Create));

        // step 3
        document.Open();

        // step 4
        iTextSharp.text.pdf.PdfImportedPage page = writer.GetImportedPage(reader, 1);
        iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
        iTextSharp.text.pdf.PdfTemplate template1 = cb.CreateTemplate(pageSize.Width, pageSize.Height);

        template1.Rectangle(0, 0, pageSize.Width, pageSize.Height);
        template1.Rectangle(toMove.Left, toMove.Bottom, toMove.Width, toMove.Height);
        template1.EoClip();
        template1.NewPath();
        template1.AddTemplate(page, 0, 0);

        iTextSharp.text.pdf.PdfTemplate template2 = cb.CreateTemplate(pageSize.Width, pageSize.Height);

        template2.Rectangle(toMove.Left, toMove.Bottom, toMove.Width, toMove.Height);
        template2.Clip();
        template2.NewPath();
        template2.AddTemplate(page, 0, 0);
        cb.AddTemplate(template1, 0, 0);
        cb.AddTemplate(template2, -20, -2);

        // step 5
        document.Close();
        reader.Close();