当批量打印来自控制台应用程序的RDLC报告时处理流
本文关键字:RDLC 报告 处理 应用程序 控制台 打印 | 更新日期: 2023-09-27 18:13:25
我正在从控制台应用程序打印报告。我开始使用微软规定的方式(http://msdn.microsoft.com/en-us/library/ms252172(v=vs.100).aspx)。在这种技术中,可以像这样呈现报告:
report.Render("Image", deviceInfo, CreateStream, out warnings);
其中CreateStream是一个函数的回调:
private Stream CreateStream(string name, string fileNameExtension,
Encoding encoding, string mimeType, bool willSeek)
{
Stream stream = new FileStream(name + "." + fileNameExtension,
FileMode.Create);
m_streams.Add(stream);
return stream;
}
这个想法是你呈现你想要的报告文件,留下流打开和收集在一个数组中。然后,一旦它们全部呈现,您就可以遍历该数组,使用这些打开的流将文件内容发送到打印机。
这对一些报告很有效,但在我的情况下,我要打印大约1500个单页报告。显然,如果不严重降低性能,我就不能让所有这些流保持开放状态。所以,我修改了一些东西。我创建了一个类级流对象(RenderStream),我在CreateStream回调中使用,并将文件名保存在集合中。
RenderStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read);
RenderedFileList.Add(fileName);
然后在Report.Render()函数返回后使用RenderStream.Dispose()。
这样我的流保持关闭和处理。当所有的导出都完成后,当我去打印时,在PrintPage事件中我这样做:
private void PrintPage(object sender, PrintPageEventArgs ev)
{
using (Stream stream = new FileStream(RenderedFileList[fileCounter], FileMode.Open, FileAccess.Read, FileShare.Read))
{
Metafile pageImage = new Metafile(stream);
ev.Graphics.DrawImage(pageImage, ev.PageBounds);
}
}
现在,这就是问题所在。虽然I 通常打开流到那些呈现的文件没有问题,但在打印时访问这些文件的尝试中,约有5%返回异常,报告文件不可访问,因为它被另一个进程打开了。
我能做些什么来解决这个问题?
我面对同样的问题,从另一种方式出来。参考你的链接,我遵循了这种方法。
保存一个列表以获取流创建的所有文件:
private List<string> _emfFiles = new List<string>();
修改CreateStream
方法为:
private Stream CreateStream(string name, string fileNameExtension,
Encoding encoding, string mimeType, bool willSeek)
{
Stream stream = new FileStream(name + "." + fileNameExtension, FileMode.Create);
m_streams.Add(stream);
//Get all the files
_emfFiles.Add(name + "." + fileNameExtension);
return stream;
}
以便_emfFiles
列表包含流创建的所有EMF文件。然后,在Disposed
法中;
public void Disposed()
{
if (m_streams != null)
{
foreach (Stream stream in m_streams)
stream.Close();
m_streans = null;
}
//Delete every file created by the stream
foreach (string file in _emfFiles)
{
if (File.Exists(file))
File.Delete(file);
}
}
最后在Run
方法中调用Disposed
方法:
private void Run()
{
LocalReport report = new LocalReport();
report.ReportPath = "Report.rdlc";
report.DataSources.Add(new ReportDataSource("Sales", LoadSalesData()));
Export(report);
m_currentPageIndex = 0;
Print();
//After finishing printing delete those EMF files
Disposed();
}
这个方法适合我。
为什么使用FileStream而不是MemoryStream?
这个对我有效:
private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
{
Stream stream = new MemoryStream();
m_streams.Add(stream);
return stream;
}