There are scenarios which require to print images on SSRS reports in Dynamics 365 for Finance and Operations. How you will achieve this depends on where the images are stored.
Let's say that you need to display product images on the Sales Order Confirmation or Sales Quotation report, to make it look more appealing. In this case the item (i.e. product) images are stored in the database, as Attachments (DocuRef) of the EcoResProductImage table.
To print the listed product images on Sales Order Confirmation you will need to take the following steps:
- In the report temporary table add a new field ProductImage of type container (or the Bitmap extended data type).
- Extend the report DP class (SalesConfirmDP) with the X++ code which fills the new ProductImage field with the image retrieved from the EcoResProductImage table.
1234567891011121314// Get the product image thumbnail.ImageReference imageData =EcoResProductImage::releasedProductImage(inventTable, EcoResProductImageSize::Thumbnail);container productImageThumbnailContainer;if (imageData.parmImageType() == ImageReference::Base64Type){System.Byte[] productImageThumbnailByteArray =DocGlobalHelper::convertFromBase64String(imageData.parmImageData());productImageThumbnailContainer =DocGlobalHelper::convertBytesToContainer(productImageThumbnailByteArray);}salesConfirmDetailsTmp.ProductImage = productImageThumbnailContainer;
The DocGlobalHelper::convertFromBase64String() method looks like this:
12345678910111213141516public static System.Byte[] convertFromBase64String(str _base64String){System.Byte[] bytes;if (_base64String != ''){try{bytes = System.Convert::FromBase64String(_base64String);}catch (Exception::CLRError){DocGlobalHelper::handleClrException(funcName(), 'Converting from base64String to byte array failed');}}return bytes;}And the DocGlobalHelper::convertBytesToContainer() method looks like the following:
12345678910111213141516171819202122232425262728293031323334353637383940public static container convertBytesToContainer(System.Byte[] _bytes){System.IO.MemoryStream memStream;container bytesAsContainer;Binary binary;int byteCount;void cleanUp(){if (memStream != null){memStream.Close();memStream.Dispose();}}if (_bytes != null){byteCount = _bytes.get_Length();if (byteCount > 0){try{memStream = new System.IO.MemoryStream(_bytes);binary = Binary::constructFromMemoryStream(memStream);bytesAsContainer = binary.getContainer();cleanUp();}catch (Exception::CLRError){DocGlobalHelper::handleClrError(funcName(), 'Conversion from byte array to container failed');cleanUp();throw Exception::Error;}return bytesAsContainer;}}return conNull();} - Use the new field in the report design with the Image design element:
How to use images in your reports with Docentric
You can easily use images in a Docentric design by using the similar code but customizing the report’s Docentric DSP class instead.
Remember, you don’t have to introduce a new field on the report temporary table nor to extend the report DP class. Just put the following code in your Docentric DSP class, within the addDataFieldsForRdpTableRecord() method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
... // Add item images if available. InventTable inventTable = InventTable::find(_currentLine.ItemId); DocXmlRecord inventTableDataRecord = _addingRecord.addChildRecord(inventTable); // Get the product image thumbnail. ImageReference imageData = EcoResProductImage::releasedProductImage(inventTable, EcoResProductImageSize::Thumbnail); container productImageThumbnailContainer; if (imageData.parmImageType() == ImageReference::Base64Type) { System.Byte[] productImageThumbnailByteArray = DocGlobalHelper::convertFromBase64String(imageData.parmImageData()); productImageThumbnailContainer = DocGlobalHelper::convertBytesToContainer(productImageThumbnailByteArray); } inventTableDataRecord.addCalculatedField('ProductImage', productImageThumbnailContainer); // Add other product fields. inventTableDataRecord.addDisplayMethod(tableMethodStr(InventTable, productDimensionGroupName)); inventTableDataRecord.addDisplayMethod(tableMethodStr(InventTable, productSubtype)); inventTableDataRecord.addCalculatedField('ProductName', inventTable.productName(currentUserLanguage())); inventTableDataRecord.addCalculatedField('ProductDescription', inventTable.productDescription(currentUserLanguage())); ... |
After you generate your DDSP file using the changed Docentric DSP class you will be able to design beautiful sales order confirmations or quotes with product images, directly in MS Word using Docentric Designer.
Your designing efforts will result in quite amazing public facing documents :).