简体   繁体   English

在iTextSharp中更改PDF文档的订单页面

[英]Change order pages of PDF document in iTextSharp

I'm trying to change reorder pages of my PDF document, but i can't and I don't know why. 我正在尝试更改PDF文档的重新排序页面,但是我不能,我也不知道为什么。

I read several articals about changing order, it's java(iText) and i have got few problems with it.( exampl1 , exampl2 , example3 ). 我读到切换顺序几个快速举报通道,它的Java(iText的)和我有几个问题吧。( exampl1exampl2示例3 )。 This example on c#, but there is using other method( exampl4 ) 这个例子在c#上,但是有使用其他方法的例子exampl4

I want take my TOC on 12 page and put to 2 page. 我想把我的目录放在12页上,放到2页上。 After 12 page I have other content. 12页之后,我还有其他内容。 This is my template for change order of pages: 这是我的页面更改顺序模板:

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

This is my method for changing order of pages: 这是我更改页面顺序的方法:

         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();
            }
    }

Here is call to method: 这是对方法的调用:

  ...
  doc.Close();

  ChangePageOrder(filePath);

What am I doing not right? 我在做什么不对?

Thank you. 谢谢。

Your code can't work because you are using path to create the PdfReader as well as to create the FileStream . 您的代码无法正常工作,因为您正在使用path创建PdfReader以及创建FileStream You probably get an error such as "The file is in use" or "The file can't be accessed". 您可能会收到诸如“正在使用文件”或“无法访问文件”之类的错误。

This is explained here: 此处说明:

You create a MemoryStream() named baos , but you aren't using that object anywhere. 您创建了一个名为baosMemoryStream() ,但没有在任何地方使用该对象。 One way to solve your problem, is to replace the FileStream when you first create your PDF by that MemoryStream , and then use the bytes stored in that memory stream to create a PdfReader instance. 解决问题的一种方法是,当您首先通过该MemoryStream创建PDF时,替换FileStream ,然后使用存储在该内存流中的字节创建一个PdfReader实例。 In that case, PdfStamper won't be writing to a file that is in use. 在这种情况下, PdfStamper将不会写入正在使用的文件。

Another option would be to use a different path . 另一种选择是使用其他path For instance: first you write the document to a file named my_story_unordered.pdf (created by PdfWriter ), then you write the document to a file named my_story_reordered.pdf (created by PdfStamper ). 例如:首先,将文档写入名为my_story_unordered.pdf (由PdfWriter创建)的文件,然后将文档写入名为my_story_reordered.pdf (由PdfStamper创建)的文件。

It's also possible to create the final document in one go. 也可以一次创建最终文档。 In that case, you need to switch to linear mode. 在这种情况下,您需要切换到线性模式。 There's an example in my book "iText in Action - Second Edition" that shows how to do this: MovieHistory1 我的书“ iText in Action-Second Edition”中有一个示例演示了如何执行此操作: MovieHistory1

In the C# port of this example, you have: 在此示例的C#端口中,您具有:

writer.SetLinearPageMode();

In normal circumstances, iText will create a page tree with branches and leaves. 在正常情况下,iText将创建带有分支和叶子的页面树。 As soon aa branch has more than 10 leaves, a new branch is created. 分支的叶子数超过10后,将创建一个新分支。 With setLinearPageMode() , you tell iText not to do this. 使用setLinearPageMode() ,您可以告诉iText不要这样做。 The complete page tree will consist of one branch with nothing but leaves (no extra branches). 完整的页面树将由一个分支组成,除了叶子外什么都没有(没有多余的分支)。 This is bad from the point of view of performance when viewing the document, but it's acceptable if the number of pages in your document is limited. 从查看文档时的性能来看,这是很不好的,但是如果文档中的页数受到限制,这是可以接受的。

Once you've switched to page mode, you can reorder the pages like this: 切换到页面模式后,您可以按以下方式重新排列页面:

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);

Summarized: if your document doesn't have many pages, use the ReorderPages method. 总结:如果您的文档没有很多页面,请使用ReorderPages方法。 If your document has many pages, use the method you've been experimenting with, but do it correctly. 如果您的文档有很多页面,请使用您尝试过的方法,但请正确执行。 Don't try to write to the file that you are still trying to read. 不要尝试写入仍在尝试读取的文件。

Without going into details about what you should do you can loop through all pages from a pdf, put them into a new pdf doc with all the pages. 无需详细说明应执行的操作,就可以遍历pdf中的所有页面,将它们与所有页面放入新的pdf文档中。 You can put your logic inside the for loop. 您可以将逻辑放入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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM