0
votes

Below code works fine on iTextSharp 5.2.1

var file= new FileInfo(args[0]);
string name = file.Name.Substring(0,file.Name.LastIndexOf("."));                
// we create a reader for a certain document
var reader = new PdfReader(args[0]);
// we retrieve the total number of pages
int numberOfPages = reader.NumberOfPages;
Console.WriteLine("There are " + n + " pages in the original file.");
Document document;
string filename;
PdfCopy copy;

for (int pageNumber = 1; i <= numberOfPages; i++) 
{
    filename = pageNumber.ToString();
    filename = "_" + filename + ".pdf";
    // step 1: creation of a document-object
    document = new Document(reader.GetPageSizeWithRotation(pageNumber ));
    // step 2: we create a writer that listens to the document
    copy = new PdfCopy(document, new FileStream(name + filename,FileMode.Create));
    // step 3: we open the document
    document.Open();
    copy.AddPage(copy.GetImportedPage(reader, pageNumber));
    // step 5: we close the document
    document.Close();
}

But it throws below error on iTextSharp 5.5.0,

The page 1 was requested but the document has only 0 pages.

it seems like that the last line actually tampered the reader instance. Could someone help me figure it out? Now I walkaround this by recreating a PdfReader instance for each page, but that is slow for large PDF file.

2

2 Answers

3
votes

I finally nailed it. It's a change of iText in recent version that caused this issue, specifically, the issue lies in the WriteAllPages of the PdfReaderInstance.cs file. In it, the line

file.Close();

is the culprit. The reason is that Document.Close method will call PdfCopy.Close method which will in turn call PdfReaderInstance.WriteAllPages method and then all hells break loose.

On the surface, it seems a good practice to close the file, but really, it's none of your business, damn you, PdfReaderInstance.

Hope this info helps others.

2
votes

iTextSharp page numbers are one-based, not zero. These two lines are accounting for this correctly:

pagenumber = i + 1;

document = new Document(reader.GetPageSizeWithRotation(pagenumber));

However this line is still going back to the zero-based index of your loop:

copy.AddPage(copy.GetImportedPage(reader, i));

You could just change that to:

copy.AddPage(copy.GetImportedPage(reader, pagenumber));

Of you could just make your entire loop one-based and not think about having to add one every once in a while

for (int pagenumber = 1; pagenumber <= n; pagenumber++) 
{
    filename = pagenumber.ToString();
    while (filename.Length< digits) filename = "0" + filename;
    filename = "_" + filename + ".pdf";
    // step 1: creation of a document-object
    document = new Document(reader.GetPageSizeWithRotation(pagenumber));
    // step 2: we create a writer that listens to the document
    copy = new PdfCopy(document, new FileStream(name+filename,FileMode.Create));
    // step 3: we open the document
    document.Open();
    copy.AddPage(copy.GetImportedPage(reader, pagenumber));
    // step 5: we close the document
    document.Close();
}