First of all, let me say that i really love the pdfsharp library. I use it extensively in my current project, which involves merging pdf files and
adding page counters etc. to it.
Unfortunately I have no control over the pdf files that are to be merged, so I sometimes got the "iref stream" error message. At the same time I really want to stick with pdfsharp because it is imho a pdf api with a very nice and clear api.
So I developed an (ugly) workaround which I post here to give back something to this community.
the idea is simple: If pdfsharp fails to import a pdf file, use Itextsharp to open the document and write a compatible pdf, which can then be imported again with pdfsharp.
Here is the code :
Code:
static public class CompatiblePdfReader
{
/// <summary>
/// uses itextsharp 4.1.6 to convert any pdf to 1.4 compatible pdf, called instead of PdfReader.open
/// </summary>
/// <param name="sFilename"></param>
/// <returns></returns>
static public PdfDocument Open(string sFilename)
{
PdfDocument reader = new PdfDocument();
try {
reader = PdfReader.Open(sFilename, PdfDocumentOpenMode.Import);
}
catch (PdfSharp.Pdf.IO.PdfReaderException) {
//workaround if pdfsharp doesnt dupport this pdf
string newName = WriteCompatiblePdf(sFilename);
reader = PdfReader.Open(newName, PdfDocumentOpenMode.Import);
}
return reader;
}
/// <summary>
/// uses itextsharp 4.1.6 to convert any pdf to 1.4 compatible pdf
/// </summary>
/// <param name="sFilename"></param>
/// <returns></returns>
static private string WriteCompatiblePdf(string sFilename)
{
string sNewPdf = Globals.TempPath + Guid.NewGuid().ToString() + ".pdf";
iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(sFilename);
// we retrieve the total number of pages
int n = reader.NumberOfPages;
// step 1: creation of a document-object
iTextSharp.text.Document document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
// step 2: we create a writer that listens to the document
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, new FileStream(sNewPdf, FileMode.Create));
//write pdf that pdfsharp can understand
writer.SetPdfVersion(iTextSharp.text.pdf.PdfWriter.PDF_VERSION_1_4);
// step 3: we open the document
document.Open();
iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
iTextSharp.text.pdf.PdfImportedPage page;
int rotation;
int i = 0;
while (i < n)
{
i++;
document.SetPageSize(reader.GetPageSizeWithRotation(i));
document.NewPage();
page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
}
// step 5: we close the document
document.Close();
return sNewPdf;
}
}
You will have to modify the code a bit to make it work (this is jsut a "copy and patse" from my current project).
I chose itextsharp 4.1.6 because version 5 had problems with some pdfs in my "testsuite".