2011-03-19 6 views
4

J'utilise iText pour générer un document PDF composé de plusieurs copies de presque la même information.Comment créer des documents en plusieurs exemplaires avec iText

E.g .: Une facture. Une copie est donnée au client, une autre est déposée et une troisième est donnée à un comptable pour la tenue de livres.

Toutes les copies doivent être exactement les mêmes, sauf pour un petit morceau de texte qui indique qui est la copie (Client, Comptabilité, Fichier, ...).

Il y a deux scénarios possibles (je ne sais pas si la solution est la même pour les deux):

a) Chaque copie va dans une autre page .

b) Toutes les copies va dans la même page (le papier ont des trous de coupe à separete copies).

Il y aura une classe wrapper ou helper qui utilise iText pour générer le PDF afin de pouvoir faire quelque chose comme var pdf = HelperClass.CreateDocument(DocuemntInfo info);. Le problème des copies multiples sera résolu dans ce wrapper/helper.

Que fournit iText pour accomplir ceci? Ai-je besoin d'écrire chaque élément du document plusieurs fois dans différentes positions/pages? Ou est-ce qu'iText fournit un moyen d'écrire une copie dans le document et de la copier dans une autre position/page?


Note: C'est un projet .Net, mais je tagged la question avec Java et C# parce que ce qustion est sur la façon d'utiliser iText correctement la réponse aidera les développeurs laguage.

Répondre

2

Voici comment je vois cela fonctionner.

PdfReader reader = new PdfReader(templatePDFPath); 
Document doc = new Document(); 
PdfWriter writer = PdfWriter.createInstance(doc, new FileOutputStream("blah.pdf")); 

PdfImportedPage inputPage = writer.getImportedPage(reader, 1); 

PdfDirectContent curPageContent = writer.getDirectContent(); 

String extraStuff[] = getExtraStuff(); 

for (String stuff : extraStuff) { 
    curPageContent.saveState(); 
    curPageContent.addTemplate(inputPage /*, x, y*/); 
    curPageContent.restoreState(); 

    curPageContent.beginText(); 
    curPageContent.setTextMatrix(x, y); 
    curPageContent.setFontAndSize(someFont, someSize); 

    // the actual work: 
    curPageContent.showText(stuff); 

    curPageContent.EndText();  

    // save the contents of curPageContent out to the file and reset it for the next page. 
    doc.newPage(); 
} 

C'est le strict minimum de travail de l'ordinateur. Assez efficace, et il en résultera un plus petit PDF. Plutôt que d'avoir N copies de cette page, avec des ajustements, vous avez une copie de cette page qui est réutilisée sur N pages, avec quelques petits ajustements sur le dessus.

Vous pouvez faire la même chose et utiliser les paramètres "x, y" dans addTemplate pour les dessiner tous sur la même page. Dépend de vous.PS: vous devez déterminer à l'avance les coordonnées pour setTextMatrix.

+1

+1 Mais il y a quelques erreurs et méthodes manquantes donc quiconque utilisant ce code devrait être conscient de ce qui suit: 1) il faut ouvrir au document en émettant doc.open(); (après l'initialisation de l'auteur, voir http://stackoverflow.com/questions/9315698/the-document-is-not-open-error-only-in-production-with-itextsharp) et aussi le fermer à la fin en appelant doc.Close() ;, 2) au lieu de PdfWriter.createInstance() il devrait être getInstance(), 3) au lieu de PdfDirectContent, il devrait être PdfContentByte –

+1

Ce code est en Java et iText donc quiconque utilise ce code dans C# et iTextSharp devrait notez (outre les erreurs que j'ai signalées dans le commentaire précédent): 1) que tous les noms de méthodes commencent par une majuscule dans iTextSharp, 2) "for (String stuff: extraStuff)" devrait être dans C# "foreach (String stuff dans extraStuff) ", 3) writer.getDirectContent() est dans iTextSharp une propriété (pas une méthode) nommée DirectContent –

+0

Et c'est ce qui se passe lorsque vous écrivez du code à partir de la mémoire des gens. –

4

Si chaque copie se passe sur une page différente, vous pouvez créer un nouveau document et copier dans la page plusieurs fois. En utilisant iText en Java, vous pouvez le faire comme ceci:

// Create output PDF 
Document document = new Document(PageSize.A4); 
PdfWriter writer = PdfWriter.getInstance(document, outputStream); 
document.open(); 
PdfContentByte cb = writer.getDirectContent(); 

// Load existing PDF 
PdfReader reader = new PdfReader(templateInputStream); 
PdfImportedPage page = writer.getImportedPage(reader, 1); 

// Copy first page of existing PDF into output PDF 
document.newPage(); 
cb.addTemplate(page, 0, 0); 
// Add your first piece of text here 
document.add(new Paragraph("Customer")); 

// Copy second page of existing PDF into output PDF 
document.newPage(); 
cb.addTemplate(page, 0, 0); 
// Add your second piece of text here 
document.add(new Paragraph("Accounting")); 

// etc... 

document.close(); 

Si vous voulez mettre toutes les copies sur la même page , le code est similaire, mais au lieu d'utiliser des zéros dans addTemplate(page, 0, 0) vous devrez définir valeurs pour la position correcte; Les numéros à utiliser dépendent de la taille et de la forme de votre facture.

Voir aussi iText - add content to existing PDF file - le code ci-dessus est basé sur le code que j'ai écrit dans cette réponse.

+0

fermer. 'document.add (new Paragraph (" blah "))' collera toujours le texte dans la première ligne du document en fonction de ses marges. C'est presque certainement faux, même si je suppose que vous pourriez mélanger vigoureusement les marges afin que ce soit juste. Plus facile de dessiner directement le texte ainsi que la page importée. –

+0

Merci pour la réponse – pudaykiran

1

Vous pouvez également utiliser PDfCopy ou PDfSmartCopy pour ce faire.

PdfReader reader = new PdfReader("Path\To\File"); 
Document doc = new Document();   
PdfCopy copier = new PdfCopy(doc, ms1); 
//PdfSmartCopy copier = new PdfSmartCopy(doc, ms1); 
doc.Open(); 
copier.CloseStream = false;  

PdfImportedPage inputPage = writer.GetImportedPage(reader, 1); 
PdfContentByte curPageContent = writer.DirectContent;    

for (int i = 0; i < count; i++) 
{   
    copier.AddPage(inputPage);   
} 
doc.Close();       
ms1.Flush(); 
ms1.Position = 0; 

La différence entre PdfCopy et PdfSmartCopy est que les copies PdfCopy l'ensemble PDF pour chaque page, tandis que PdfSmartCopy crée un PDF qui contient en interne un seul exemplaire et toutes les pages y font référence, ce qui dans un fichier plus petit et moins de bande passante sur un réseau, mais il utilise plus de mémoire sur le serveur et prend plus de temps à traiter.

Questions connexes