Questo sito utilizza i cookie per migliorare servizi ed esperienza del lettore. Se decidi di continuare la navigazione consideriamo che accetti il loro uso . Per e informazioni sulla Privacy leggere la Google Policies Privacy

Se continui nella navigazione accetti il loro uso. OK

lunedì 9 agosto 2010

Inserimento di un codice a barre in un report RDLC

I report RDLC sono un potente mezzo messo a disposizione agli sviluppatori .NET per la creazione di report, potrebbero non avere l'eleganza di strumenti professionali, ma si distinguono per semplicità d'uso e facilità di installazione. Spesso ci si trova a dover inserire immagini al suo interno e ci si accorge che in fase di generazione di un PDF l'immagine stessa è inserita come parte dello stream del file. Fantastico penso io, questo vuol dire che se per esempio devo creare un bel report con un codice a barre stampigliato sopra mi basta indicarlo come font da usare per un'etichetta di testo e il gioco è fatto, durante il packing del file verrà inserita la risorsa del font (cosa che il formato pdf permette perfettamente) e anche se porto il mio pdf su un computer in cui non c'è il font indicato (o, ancor meglio, lo renderizzo da un'applicazione ASP.NET e lo faccio scaricare a chiunque), esso verrà comunque renderizzato senza problemi. E qui il mio sogno si infrange. Il font NON viene inserito come risorsa ma solo come riferimento, di conseguenza se nel mio sistema non c'è installato quel determinato font leggerò una serie senza senso di numeri e lettere.
A questo punto ho cominciato a cercare una libreria che mi permettesse di aprire un file pdf esistente (il file generato dal mio motore di reportistica) e modificarlo per inserire 'a mano' il codice a barre.
Nei miei pellegrinaggi mi sono imbattuto in una libreria opensource iTextSharp che è il porting .NET della potente libreria iText di java.
La mia idea iniziale era quella di andare ad includere il file ttf come risorsa all'interno del pdf, idea che poi è naufragata per la mia scarsa conoscenza della libreria (se qualcuno è riuscito a fare questo, può postare un commento sul blog nel quale può spiegare la tecnica a tutti o deridermi!).
Alla fine mi sono arreso a una soluzione paliativa, ma comunque funzionante. La libreria iTextSharp contiene svariate classi per la generazione di codici a barre, quindi non mi serviva altro che utilizzarle per modificare il mio file.
Partiamo con i passi base: prendere lo stream del nostro file pdf e renderlo modificabile con iTextSharp:
MemoryStream m = new MemoryStream();
PdfReader r = new PdfReader(pdfContent);
PdfStamper pdf = new PdfStamper(r, m);
Lo strem iniziale conterrà il file finale con la modifica, il PdfReader permette di leggere il flusso stream del file (pdfContent è un byte[]) e PdfStamper permette di prendere il file letto dal reader, eseguire delle modifice e scrivere il nuovo contenuto nel MemoryStream.
A questo punto dobbiamo andare a aprire una pagina del pdf (alla fine inseriremo il codice a barre su ogni pagina), creare una classe che ci permetterà di controllare il codice a barre, stampigliarlo sopra e salvare il tutto.
for (int i = 1; i <= r.NumberOfPages; i++){
   //Craezione della classe per la generazione del codice a barre
   Barcode128 b = new Barcode128();
   b.Code = '1234656789ABCDE'
   b.StartStopText = true;
   b.GenerateChecksum = false;
   b.Extended = true;
   b.BarHeight = 30;

   //Apertura della pagina
   PdfContentByte cb = pdf.GetOverContent(i);
   iTextSharp.text.Image img = b.CreateImageWithBarcode(cb, null, null);

   //Aggiunta in una posizione fissa del codice a barre
   img.SetAbsolutePosition(200, 20);
   cb.AddImage(img);
}
pdf.Close();

Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=" + "PDF.pdf");
Response.Charset = "";
Response.ContentType = "application/pdf";
Response.BinaryWrite(m.ToArray());
Response.Flush();
Response.End();
L'unico difetto di questa tecnica è la posizione assoluta del codice a barre. Ma con un pochino di fantasia possiamo andare a cercare qualche elemento sempre presente nel pdf e a leggere la sua posizione, quindi impostare il left e il top in base a questo valore. Ma questa è un'altra storia.

1 commento:

  1. Una precisazione, credo che la codifica usata dalla classe Barcode128 sia quella C (CODE 128C) di conseguenza le lettere non sono ammesse (è una codifica più compatta però), quindi l'esempio è sbagliato!

    RispondiElimina