2010-11-29 4 views
2

Nous avons une application ASP.NET que les utilisateurs utilisent pour générer certains rapports. Jusqu'à présent, nous avions un modèle PDF contenant une image, et nous remplacions simplement cette image par celle générée par programme (graphique).
Nous avons utilisé le code de ce site pour cela: http: //blog.rubypdf.com/2007/12/12/how-to-replace-images-in-a-pdf/Remplacer plusieurs images différentes sur une page de modèle PDF avec itext (itextsharp)

Le problème est maintenant que Nous avons deux images différentes sur une page PDF, et le code du lien ci-dessus sélectionne les deux images sur une page et les remplace toutes en même temps avec notre image générée.

Quelqu'un at-il une idée de comment remplacer plusieurs images différentes sur une page avec itext?

Remerciements

Répondre

8

Ugh. D'abord, permettez-moi de réécrire une partie de cette source.

PdfReader pdf = new PdfReader("in.pdf"); 
PdfStamper stp = new PdfStamper(pdf, new FileOutputStream("c:\\out.pdf")); 
PdfWriter writer = stp.getWriter(); 
Image img = Image.getInstance("image.png"); 
PdfDictionary pg = pdf.getPageN(1); 
PdfDictionary res = pg.getAsDict.get(PdfName.RESOURCES); 
PdfDictionary xobj = res.getAsDict(PdfName.XOBJECT); 
if (xobj != null) { 
    for (Iterator<PdfName> it = xobj.getKeys().iterator(); it.hasNext();) { 
    PdfObject obj = xobj.get(it.next()); 
    if (obj.isIndirect()) { 
     PdfDictionary tg = (PdfDictionary)PdfReader.getPdfObject(obj); 
     PdfName type = tg.getAsName(PdfName.SUBTYPE)); 
     if (PdfName.IMAGE.equals(type)) { 
     PdfReader.killIndirect(obj); 
     Image maskImage = img.getImageMask(); 
     if (maskImage != null) 
      writer.addDirectImageSimple(maskImage); 
     writer.addDirectImageSimple(img, (PRIndirectReference)obj); 
     break; 
     } 
    } 
    } 
} 

Whew. Les fonctions getAs peuvent vous épargner un peu de graisse et rendre votre code beaucoup plus clair.

Maintenant. Vous devez être capable de différencier les différentes images. Si vous êtes prêt à des choses difficiles code, vous pouvez savoir ce que les noms de ressources sont et aller dans cette voie:

String imageResName[] = {"Img1", "Img2" ... }; 
Image img[] = {Image.getInstance("foo.png"), Image.getInstance("bar.png"), ... }; 
for (int i = 0; i < imageResName.length; ++i) { 
    PdfName curKey = new PdfName(imageResName[i]); 
    PdfIndirectReference ref = xobj.getAsIndirect(curKey); 
    PdfReader.killIndirect(ref); 
    Image maskImage = img[i].getImageMask(); 
    if (maskImage != null) { 
    writer.addDirectImageSimple(maskImage); 
    } 
    writer.addDirectImageSimple(img[i], (PRIndirectReference)ref); 
} 

Si vous n'êtes pas prêt à aller avec les noms de ressources hardcoded (et personne ne faute vous, bien au contraire, en particulier lorsque l'ordre de leur apparition (et donc le nombre à la fin) dépend de leur ordre dans une carte de hachage ... [shudder]), vous pouvez différencier en fonction de la largeur et de la hauteur de l'image.

//keep the original for loop, stepping through resource names 
if (PdfName.IMAGE.equals(type)) { 
    float width = tg.getAsNumber(PdfName.WIDTH).floatValue(); 
    float height = tg.getAsNumber(PdfName.HEIGHT).floatValue(); 

    Image img = getImageFromDimensions(width, height); 

    Image maskImage = img.getImageMask(); 
    ... 
} 
+0

Merci beaucoup! Vous semblez avoir une vaste connaissance de l'itext, pourriez-vous, s'il vous plaît, nous diriger vers des matériaux où nous pourrions améliorer nos compétences sur itext? Je vous remercie. –

+0

Je travaille avec iText depuis ... 06? Je suis un committer depuis environ deux ans maintenant. J'ai travaillé avec des logiciels PDF en général pendant plus d'une décennie, presque 14 ans. Deux façons de s'améliorer: Lire le livre ("iText in Action" 2ème édition, écrit par l'auteur original), et lire la source. Un dévouement féroce au pape. Lisez la [spécification PDF] (http://www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf). Apprenez la section «syntaxe» par cœur et sachez où chercher à peu près tout le reste. –

+0

Merci beaucoup. Bravo –

2

Juste une note que, parfois, l'image sera imbriquée sous une forme, il est donc sage de faire une fonction qui sera appelée récursive. Quelque chose comme ceci:

public void StartHere() 
{ 
    PdfReader pdf = new PdfReader("in.pdf"); 
    PdfStamper stp = new PdfStamper(pdf, new FileOutputStream("c:\\out.pdf")); 
    PdfWriter writer = stp.getWriter(); 
    Image img = Image.getInstance("image.png"); 
    PdfDictionary pg = pdf.getPageN(1); 
    replaceImage(pg, writer,img); 
} 

private void replaceImage(PdfDictionary pg, PdfWriter writer,Image img) 
{ 
    PdfDictionary res = pg.getAsDict.get(PdfName.RESOURCES); 
    PdfDictionary xobj = res.getAsDict(PdfName.XOBJECT); 
    if (xobj != null) { 
     for (Iterator<PdfName> it = xobj.getKeys().iterator(); it.hasNext();) { 
     PdfObject obj = xobj.get(it.next()); 
     if (obj.isIndirect()) { 
      PdfDictionary tg = (PdfDictionary)PdfReader.getPdfObject(obj); 
      PdfName type = tg.getAsName(PdfName.SUBTYPE)); 
      if (PdfName.IMAGE.equals(type)) 
      { 
      PdfReader.killIndirect(obj); 
      Image maskImage = img.getImageMask(); 
      if (maskImage != null) 
       writer.addDirectImageSimple(maskImage); 
      writer.addDirectImageSimple(img, (PRIndirectReference)obj); 
      break; 
      } 
      else if(PdfName.FORM.equals(type)) 
      { 
       replaceImage(tg, writer,img); 
      } 
     } 
     } 
    } 
Questions connexes