I've built a wrapper for a LocalReport
and I would like to hear your suggestions about it:
public class ReportWrapper : IDisposable
{
private string _reportResource;
private LocalReport _report = new LocalReport();
private int m_currentPageIndex;
private IList<Stream> m_streams;
public Dictionary<string, object> ReportDataSource { get; private set; }
public PrinterSettings printSettings { get; set; }
/// <summary>
/// true, wenn die Seite im Querformat gedruckt werden soll, andernfalls false.
/// Der Standardwert ist false
/// </summary>
public bool Landscape { get; set; }
public string FileName { get; set; }
public ReportWrapper(string ReportResource)
{
this._reportResource = ReportResource;
this.ReportDataSource = new Dictionary<string, object>();
this._report = new LocalReport(); ;
}
public void Print()
{
_report.ReportEmbeddedResource = _reportResource;
foreach (var item in ReportDataSource)
_report.DataSources.Add(CreateReportDataSource(item.Key, item.Value));
Export();
Printing();
}
public void toPDF(string FilePath)
{
_report.ReportEmbeddedResource = _reportResource;
foreach (var item in ReportDataSource)
_report.DataSources.Add(CreateReportDataSource(item.Key, item.Value));
var fi = new FileInfo(string.Format(CultureInfo.CurrentCulture, "{0}/{1}", FilePath, FileName));
if (fi.Exists)
fi = CreateNewFileName(fi);
Byte[] results = _report.Render("PDF");
File.WriteAllBytes(fi.FullName, results);
}
private static FileInfo CreateNewFileName(FileInfo fi)
{
int modifier = 1;
while (true)
{
var tempFi = new FileInfo(string.Format(CultureInfo.CurrentCulture, "{0}/{1}({2}){3}", fi.Directory, Path.GetFileNameWithoutExtension(fi.Name), modifier, fi.Extension));
if (!tempFi.Exists)
{
fi = tempFi;
break;
}
modifier++;
}
return fi;
}
public static ReportDataSource CreateReportDataSource(string Name, object Source)
{
var bindingSource = new BindingSource();
bindingSource.DataSource = Source;
return new ReportDataSource(Name, bindingSource);
}
// Routine to provide to the report renderer, in order to
// save an image for each page of the report.
private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
{
Stream stream = new MemoryStream();
m_streams.Add(stream);
return stream;
}
// Export the given report as an EMF (Enhanced Metafile) file.
private void Export()
{
string deviceInfo = @"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
</DeviceInfo>";
Warning[] warnings;
m_streams = new List<Stream>();
_report.Render("Image", deviceInfo, CreateStream, out warnings);
foreach (Stream stream in m_streams)
stream.Position = 0;
}
private void PrintPage(object sender, PrintPageEventArgs ev)
{
Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);
// Adjust rectangular area with printer margins.
Rectangle adjustedRect = new Rectangle(
ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
ev.PageBounds.Width,
ev.PageBounds.Height);
// Draw a white background for the report
ev.Graphics.FillRectangle(Brushes.White, adjustedRect);
// Draw the report content
ev.Graphics.DrawImage(pageImage, adjustedRect);
// Prepare for the next page. Make sure we haven't hit the end.
m_currentPageIndex++;
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
}
private void Printing()
{
if (m_streams == null || m_streams.Count == 0)
throw new Exception("Error: no stream to print.");
PrintDocument printDoc = new PrintDocument();
printDoc.PrinterSettings = printSettings;
printDoc.DocumentName = FileName;
printDoc.DefaultPageSettings.Landscape = Landscape;
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
m_currentPageIndex = 0;
printDoc.Print();
}
public LocalReport getReport()
{
return _report;
}
public string ReportEmbeddedResource
{
get { return _reportResource; }
}
public SubreportProcessingEventHandler SubreportProcessing { get; set; }
#region IDisposable
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if (disposing)
{
_report.Dispose();
}
}
disposed = true;
}
#endregion
}
Usage example:
var rw = new ReportWrapper("name.space.to.MyReport.rdlc");
rw.ReportDataSource.Add("Source1", someObject);
rw.ReportDataSource.Add("Source2", someDetailobject);
rw.SubreportProcessing += YourSubDataSource;
public void YourSubDataSource(object sender, SubreportProcessingEventArgs e)
{
\\Logic
}