Hi My applion is MVC3 c#, I am using itextsharp to produce PDF files for pre disgned forms. In this application I have to different forms. To generate a form I use:
public ActionResult TestPDF(long learnerID = 211, long courseID = 11)
{
var caseList = _studyCaseSvc.ListStudyCases().Where(x => x.Course_ID == courseID);
try
{
MemoryStream memoryStream = new MemoryStream();
PdfConcatenate whole = new PdfConcatenate(memoryStream);
foreach (var ca in caseList)
{
byte[] part = null;
if (ca.CaseType == "CTA")
{
part = GenerateEvaluationCAT_PDF(learnerID, ca.ID);
}
else if (ca.CaseType == "CTAH")
{
part = GenerateEvaluationCATH_PDF(learnerID, ca.ID);
}
else
{
part = null;
}
if (part != null)
{
PdfReader partReader = new PdfReader(part);
whole.AddPages(partReader);
partReader.Close();
}
}
whole.Close();
byte[] byteInfo = memoryStream.ToArray();
SendPdfToBrowser(byteInfo);
}
catch (Exception ex)
{
}
return null;
}
I get this error: An item with the same key has already been added. The error happens at AddPages. So I developed this simpler test:
private void merge()
{
try
{
FileStream output = new FileStream("p3.pdf", FileMode.Create);
PdfConcatenate pdfConcatenate = new PdfConcatenate(output, true);
PdfReader r1 = new PdfReader("p2.pdf");
MemoryStream memoryStream = new MemoryStream();
PdfStamper pdfStamper = new PdfStamper(r1, memoryStream);
pdfStamper.FormFlattening = true;
pdfStamper.Close();
PdfReader r2 = new PdfReader(memoryStream.ToArray());
//pdfConcatenate.AddPages(tempReader);
pdfConcatenate.Open();
int n = r1.NumberOfPages;
for (int i = 1; i <= n; i++)
{
PdfImportedPage imp = pdfConcatenate.Writer.GetImportedPage(r1, i);
pdfConcatenate.Writer.AddPage(imp);
}
pdfConcatenate.Writer.FreeReader(r1);
pdfStamper.Close();
r1.Close();
pdfConcatenate.Close();
}
catch (Exception ex)
{
}
}
Same error.
Well, the problem is the misconception that you can combine multiple PDF files into one by simply concatenating them. That is wrong for PDFs (just like it is wrong for most binary file formats).
Thus, you should update your GenerateAllEvaluation_PDF method to have a PdfConcatenate instance instead of your byte Array whole, cf. http://api.itextpdf.com/itext/com/itextpdf/text/pdf/PdfConcatenate.html, open each byte array returned by your GenerateEvaluationCATH_PDF method in a PdfReader, add all pages of these readers to the PdfConcatenate and eventually return the bytes generated by that class.
EDIT (I’m more into Java than C#, thus forgive minor errors)
The PdfConcatenate can be constructed with a MemoryStream from which you can retrieve the final byte[].
PS:
PdfConcatenatemay not be a part of iTextSharp version 4.x yet but it is merely a convenience wrapper of PdfCopy and PdfSmartCopy. Thus, you may simply have a look at the sources of iTextSharp (OSS after all) and be inspired: PdfConcatenate.cs.