Reputation: 434
I am trying to print out a generated barcode on a report using RDLC, but all I get is a small red X instead.
Here's my object.
[XmlType]
[XmlRoot(IsNullable = false)]
[Serializable]
public class Voucher
{
[XmlIgnore]
public Bitmap BarcodeImg { get; set; }
[XmlElement("BarcodeImg")]
public byte[] BarcodeImgSerialized
{
get
{
if (BarcodeImg == null) return new byte[] { };
using (var Stream = new MemoryStream())
{
BarcodeImg.Save(Stream, ImageFormat.Bmp);
return Stream.ToArray();
}
}
set
{
if (value == null) { BarcodeImg = new Bitmap(50, 50); }
else
{
using (var Stream = new MemoryStream(value))
{
BarcodeImg = new Bitmap(Stream);
}
}
}
}
public string BarcodeStr { get; set; } = string.Empty;
public Voucher() { }
}
In my report, called "Report_Voucher", I have the Voucher object listed as a dataset. My image is of the name "Barcode", the MIMEType being image/BMP, an external image source, and the expression being
=First(Fields!BarcodeImg.Value, "Voucher")
I've also tried BarcodeImgSerialized.
Here's my form code...
public partial class Form_Main : Form
{
LocalReport Report;
List<Stream> Streams = new List<Stream>();
public Form_Main()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Voucher V = CreateVoucher();
DataSet Set = CreateDataSet(V);
this.RV_Main.ProcessingMode = ProcessingMode.Local;
this.Report = RV_Main.LocalReport;
Report.ReportPath = @"..\..\Report_Voucher.rdlc";
Report.DataSources.Add(new ReportDataSource("Voucher", Set.Tables[0]));
var DeviceInfo =
@"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
<PageWidth>8.5in</PageWidth>
<PageHeight>11in</PageHeight>
<MarginTop>0.25in</MarginTop>
<MarginLeft>0.25in</MarginLeft>
<MarginRight>0.25in</MarginRight>
<MarginBottom>0.25in</MarginBottom>
</DeviceInfo>";
var Warnings = new Warning[] { };
Report.EnableExternalImages = true;
Report.Render("Image", DeviceInfo, CreateStream, out Warnings);
Streams.ForEach(x => x.Position = 0);
this.RV_Main.Refresh();
}
private DataSet CreateDataSet(Voucher Voucher)
{
var Set = new DataSet();
var Serializer = new XmlSerializer(typeof(Voucher));
using (var MStream = new MemoryStream())
{
Serializer.Serialize(MStream, Voucher);
MStream.Seek(0, SeekOrigin.Begin);
Set.ReadXml(MStream);
}
return Set;
}
private Voucher CreateVoucher()
{
var BarcodeStr = "12345678901234";
var Writer = new BarcodeWriter
{
Format = BarcodeFormat.ITF,
Options = new EncodingOptions
{
Height = 80,
Width = 400,
Margin = 0,
PureBarcode = true,
}
};
var Barcode = Writer.Write(BarcodeStr);
var Voucher = new Voucher()
{
BarcodeStr = BarcodeStr,
BarcodeImg = Barcode,
};
return Voucher;
}
private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
{
var stream = new MemoryStream();
Streams.Add(stream);
return stream;
}
private void Btn_PrintReport_Click(object sender, EventArgs e)
{
if (this.Streams == null || this.Streams.Count == 0) { return; }
var Document = new PrintDocument();
Document.DefaultPageSettings.Landscape = true;
if (!Document.PrinterSettings.IsValid) { return; }
else
{
Document.PrintPage += Document_PrintPage;
Document.Print();
}
}
private void Document_PrintPage(object sender, PrintPageEventArgs e)
{
var Stream = this.Streams.First();
var Page = new Metafile(Stream);
var AdjustedRect = new Rectangle(
e.PageBounds.Left - (int)e.PageSettings.HardMarginX,
e.PageBounds.Top - (int)e.PageSettings.HardMarginY,
e.PageBounds.Width,
e.PageBounds.Height);
e.Graphics.FillRectangle(Brushes.White, AdjustedRect);
e.Graphics.DrawImage(Page, AdjustedRect);
Stream.Dispose();
Page.Dispose();
}
}
I've tried an obnoxious number of tweaks to try to get this barcode to show up, from how the serialization was done, what the report captures as the variable for the image (byte arrays, object, Bitmap), etc., and nothing I've read seems to be a fix. Does anyone know of a fix for this?
Upvotes: 1
Views: 605
Reputation: 434
The solution was to wrap the expression in the FromBase64String call:
=System.Convert.FromBase64String(First(Fields!BarcodeImg.Value, "Voucher"));
Upvotes: 1