【问题标题】:Change order pages of PDF document in iTextSharp在 iTextSharp 中更改 PDF 文档的顺序页面
【发布时间】:2016-08-26 12:46:58
【问题描述】:

我正在尝试更改我的 PDF 文档的重新排序页面,但我不能,我也不知道为什么。

我阅读了几篇关于更改顺序的文章,它是 java(iText),我几乎没有遇到任何问题。(exampl1exampl2example3)。这个例子在c#上,但是有使用其他方法(exampl4

我想将我的 TOC 放在第 12 页并放到第 2 页。 12 页之后我还有其他内容。这是我的页面更改顺序模板:

String.Format("1,%s, 2-%s, %s-%s", toc, toc-1, toc+1, n)

这是我改变页面顺序的方法:

         public void ChangePageOrder(string path)
    {
        MemoryStream baos = new MemoryStream();

        PdfReader sourcePDFReader = new PdfReader(path);
        int toc = 12;
        int n = sourcePDFReader.NumberOfPages;
        sourcePDFReader.SelectPages(String.Format("1,%s, 2-%s, %s-%s", toc, toc-1, toc+1, n));

        using (var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
            {
                PdfStamper stamper = new PdfStamper(sourcePDFReader, fs);
                stamper.Close();
            }
    }

这是对方法的调用:

  ...
  doc.Close();

  ChangePageOrder(filePath);

我做错了什么?

谢谢。

【问题讨论】:

    标签: java c# pdf itext


    【解决方案1】:

    您的代码无法运行,因为您正在使用path 创建PdfReader 以及创建FileStream。您可能会收到“文件正在使用中”或“文件无法访问”等错误。

    这里有解释:

    您创建了一个名为baosMemoryStream(),但您没有在任何地方使用该对象。解决问题的一种方法是,在您首次创建 PDF 时将 FileStream 替换为 MemoryStream,然后使用存储在该内存流中的字节创建 PdfReader 实例。在这种情况下,PdfStamper 不会写入正在使用的文件。

    另一种选择是使用不同的path。例如:首先将文档写入名为my_story_unordered.pdf(由PdfWriter 创建)的文件,然后将文档写入名为my_story_reordered.pdf(由PdfStamper 创建)的文件。

    还可以一次性创建最终文档。在这种情况下,您需要切换到线性模式。在我的“iText in Action - Second Edition”一书中有一个例子说明了如何做到这一点:MovieHistory1

    在本示例的 C# 端口中,您有:

    writer.SetLinearPageMode();
    

    在正常情况下,iText 会创建一个带有分支和叶子的页面树。只要一个分支有超过 10 个叶子,就会创建一个新分支。使用setLinearPageMode(),您告诉 iText 不要这样做。完整的页面树将由一个只有叶子的分支组成(没有额外的分支)。从查看文档时的性能的角度来看,这很糟糕,但如果文档中的页数有限,这是可以接受的。

    切换到页面模式后,您可以像这样重新排列页面:

    document.NewPage();
    // get the total number of pages that needs to be reordered
    int total = writer.ReorderPages(null);
    // change the order
    int[] order = new int[total];
    for (int i = 0; i < total; i++) {
      order[i] = i + toc;
      if (order[i] > total) {
        order[i] -= total;
      }
    }
    // apply the new order
    writer.ReorderPages(order);
    

    总结:如果您的文档页数不多,请使用ReorderPages 方法。如果您的文档有很多页,请使用您一直在尝试的方法,但要正确执行。不要尝试写入您仍在尝试读取的文件。

    【讨论】:

    • 我尝试使用ReorderPages,但文档已损坏。怎么了?我复制了你的代码并把它放在创建 toc 之后。
    • 网站上分享的例子有效;不要指望任何人能够回答您的问题“出了什么问题?”你假设人们可以看到你在做什么。这不是真的。从你到目前为止的所有问题中,我只知道你不是开发人员。您只是从其他人那里复制/粘贴代码,而不了解您在做什么。我认为这是你最大的错误。我不认为任何人,但你可以解决这个问题。你需要培养更好的工作态度,努力变得更聪明。
    • 感谢您的批评。我会努力变得更好。
    【解决方案2】:

    无需详细说明您应该做什么,您可以循环浏览 pdf 中的所有页面,将它们放入包含所有页面的新 pdf 文档中。您可以将逻辑放在 for 循环中。

    reader = new PdfReader(sourcePDFpath);
    sourceDocument = new Document(reader.GetPageSizeWithRotation(startpage));
    pdfCopyProvider = new PdfCopy(sourceDocument, new System.IO.FileStream(outputPDFpath, System.IO.FileMode.Create));
    
    sourceDocument.Open();
    
    for (int i = startpage; i <= endpage; i++)
    {
        importedPage = pdfCopyProvider.GetImportedPage(reader, i);
        pdfCopyProvider.AddPage(importedPage);
    }
    sourceDocument.Close();
    reader.Close();
    

    【讨论】:

    • 如果我的文档足够大,它可以工作吗?
    • 不确定,有多大……我猜你的限制是你的内存。
    猜你喜欢
    • 2011-11-06
    • 2011-05-06
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 2013-10-17
    相关资源
    最近更新 更多