Home Page Home Page Tips & Tricks Caricare le immagini da un percorso fisso con Crystal Report

Caricare le immagini da un percorso fisso con Crystal Report


Spesso quando si maneggiano dati che hanno riferimenti ad immagini (tipo cataloghi o cose simili) si tende ad evitare (se possibile) di memorizzare all'interno delle tabelle direttamente tutto il file con campi BLOB.
Questo perche si appesantisce il database, l'applicazione, e non si puo' aggiornare un' immagine all'ultima versione in maniera "agile" sovrascrivendo il file.
Si tende invece a inserire il percorso UNC in un campo e a caricare il file quando viene richiesto.
Data la potenza di un oggetto come Crystal Report che supporta i campi BLOB egregiamente, ci si aspetta che sia in grado di fare per noi questo caricamento "al volo" ma cosi purtroppo non è fino alla versione XI come spiegano qui:

http://www.businessobjects.com/products/reporting/crystalreports/whatsnew.asp 

Allora per farlo lo stesso nelle precedenti versioni, si puo' decidere di "ingannare" il report, dandogli in pasto un campo fittizio e dicendogli che sia di tipo BLOB.
Cosa importantissima è appunto creare la struttura giusta con cui creare il report in fase di design in modo che si aspetti questa tipologia di campo, magari creando un database temporaneo Access dove replichiamo la struttura e ci aggiungiamo in coda il campo Image ("oggetto ole" per Access)
Proprio per quanto riguarda Access bisogna aggiungerlo a mano da dentro Access stesso perchè non supporta una conversione a questo tipo direttamente da query SQL, cosa che invece su SQL/MSDE si puo' fare tranquillamente con questa sintassi:

SELECT *, CONVERT(image,'') AS Immagine FROM MiaTabella

Cosi al Report nel caso di Access devo dare il Database con il campo BLOB e nel caso di SQL posso tranquillamente dargli un "comando" ovvero una stringa SQL senza creare campi sul DB.

A parte questa differenza che ci semplificherebbe la vita in fase di progettazione per il resto in questo campo ci dobbiamo preoccupare noi di aggiungere il contenuto in Byte[] (campo BLOB appunto) per ogni riga caricandolo dal valore del Path che abbiamo nella stessa riga utilizzando il FileStream dal namespace Sytem.IO:

Codice .NET n°1
private byte[] GetFile(string filePath)
{
FileStream str = new FileStream(filePath,FileMode.Open,FileAccess.Read);
byte[] b = new byte[str.Length];
str.Read(b, 0, b.Length);

return b;
}


e lo si carica per ogni record che risulta della mia tabella:

Codice .NET n°2
//---- leggo i file immagine e poi li parcheggio nel DB nella colonna OLE

foreach(DataRow riga in miaTab.Rows)
riga["immagine"] = GetFile((string)riga["pathimg"]);


Da tenere presente che comunque si sovraccarica un po' il programma in quanto si crea in memoria una tabella che contiene gli n byte delle immagini (e quindi dal Task Manager si puo' vedere che le risorse utilizzate aumentano) e si girano su tutte le righe percui sicuramente all'aumentare delle righe si ha un degrado delle prestazioni.

Finchè non ci viene dato il runtime della versione XI pero' non si puo' fare altrimenti ;-)

Download del Codice d'esempio
http://www.dotnethell.it/files/Crystal_Blob.zip 
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5