我正在研究WPF C#4.0项目 我正在尝试打印RDLC报告,该报告基本上是一张发票而不显示ReportViewer。我提到了以下MSDN link中的代码,并为了我的目的对其进行了修改。
以下是我正在使用的修改后的代码。
using System;
using System.IO;
using System.Data;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.Collections.Generic;
using System.Windows.Forms;
using Microsoft.Reporting.WinForms;
using System.Xml;
using System.Resources;
using System.Drawing;
using System.Reflection;
namespace POS.Classes
{
public class DirectReportPrint : IDisposable
{
private double[] PageBounds = { 0,0,0,0,0,0};
private int m_currentPageIndex;
private IList<Stream> m_streams;
private DataTable _table = new DataTable();
/// <summary>
/// Must set this to get the report data
/// </summary>
public DataTable ReportTable
{
get { return _table; }
set { _table = value; }
}
// 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 FileStream(@"..\..\" + name +
// "." + fileNameExtension, FileMode.Create);
Stream stream = new FileStream(Path.GetTempPath() + "\\" + name +
"." + fileNameExtension, FileMode.Create);
m_streams.Add(stream);
return stream;
}
private string ReadEmbeddedResource(string ResourceName)
{
var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(ResourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
string temp = result.Replace('\r',' ');
return temp;
}
}
private string ReadReportXML(string ReportName)
{
try
{
string s = " ", temp = "", t = "";
int x, y, z;
string result = ReadEmbeddedResource(ReportName);
if (result.Contains("<PageHeight>") && result.Contains("</PageHeight>"))
{
x = result.IndexOf("<PageHeight>");
y = result.IndexOf("</PageHeight>");
temp = result.Substring(x, y - x);
s += temp + "</PageHeight> ";
z = temp.IndexOf('>') + 1;
t = temp.Substring(z, temp.Length - z);
PageBounds[0] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
}
if (result.Contains("<PageWidth>") && result.Contains("</PageWidth>"))
{
x = result.IndexOf("<PageWidth>");
y = result.IndexOf("</PageWidth>");
temp = result.Substring(x, y - x);
s += temp + "</PageWidth> ";
z = temp.IndexOf('>') + 1;
t = temp.Substring(z, temp.Length - z);
PageBounds[1] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
}
if (result.Contains("<LeftMargin>") && result.Contains("</LeftMargin>"))
{
x = result.IndexOf("<LeftMargin>");
y = result.IndexOf("</LeftMargin>");
temp = result.Substring(x, y - x);
s += temp + "</LeftMargin> ";
z = temp.IndexOf('>') + 1;
t = temp.Substring(z, temp.Length - z);
PageBounds[2] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
}
if (result.Contains("<RightMargin>") && result.Contains("</RightMargin>"))
{
x = result.IndexOf("<RightMargin>");
y = result.IndexOf("</RightMargin>");
temp = result.Substring(x, y - x);
s += temp + "</RightMargin> ";
z = temp.IndexOf('>') + 1;
t = temp.Substring(z, temp.Length - z);
PageBounds[3] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
}
if (result.Contains("<TopMargin>") && result.Contains("</TopMargin>"))
{
x = result.IndexOf("<TopMargin>");
y = result.IndexOf("</TopMargin>");
temp = result.Substring(x, y - x);
s += temp + "</TopMargin> ";
z = temp.IndexOf('>') + 1;
t = temp.Substring(z, temp.Length - z);
PageBounds[4] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
}
if (result.Contains("<BottomMargin>") && result.Contains("</BottomMargin>"))
{
x = result.IndexOf("<BottomMargin>");
y = result.IndexOf("</BottomMargin>");
temp = result.Substring(x, y - x);
s += temp + "</BottomMargin> ";
z = temp.IndexOf('>') + 1;
t = temp.Substring(z, temp.Length - z);
PageBounds[5] = Math.Round(Convert.ToDouble(t.Substring(0, t.Length - 2)), 2);
}
return s;
}
catch (Exception ex)
{
return null;
}
}
// Export the given report as an EMF (Enhanced Metafile) file.
private void Export(LocalReport report, string ReportName)
{
try
{
string temp = ReadReportXML(ReportName);
if (temp != null)
{
string deviceInfo =
"<DeviceInfo>" +
" <OutputFormat>EMF</OutputFormat>"
+ temp +
"</DeviceInfo>";
Warning[] warnings;
m_streams = new List<Stream>();
report.Render("Image", deviceInfo, CreateStream,
out warnings);
foreach (Stream stream in m_streams)
stream.Position = 0;
}
else
{
throw new Exception("Something went wrong. Unable to Print Report");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
MessageBox.Show(ex.InnerException.Message);
}
}
// Handler for PrintPageEvents
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 Print()
{
PrinterSettings settings = new PrinterSettings();
if (m_streams == null || m_streams.Count == 0)
return;
PrintDocument printDoc = new PrintDocument();
printDoc.PrinterSettings.PrinterName = settings.PrinterName;
PaperSize CustomSize = new PaperSize("Custom", (int)PageBounds[1]*100, (int)PageBounds[0]*100);
CustomSize.RawKind = (int)PaperKind.Custom;
printDoc.DefaultPageSettings.PaperSize = CustomSize;
if (!printDoc.PrinterSettings.IsValid)
{
string msg = String.Format(
"Can't find printer \"{0}\".", settings.PrinterName);
MessageBox.Show(msg, "Print Error");
return;
}
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
printDoc.Print();
}
/// <summary>
/// Create a local report for Report.rdlc, load the data,
/// export the report to an .emf file, and print it.
/// Prints the report directly
/// </summary>
/// <param name="ReportName">Name of the report</param>
/// <param name="DS_Name">Dataset name for the report. Provide the name which was used during RDLC file creation</param>
public void Run(string ReportName, string DS_Name)
{
LocalReport report = new LocalReport();
report.ReportEmbeddedResource = ReportName;
report.DataSources.Add(new ReportDataSource(DS_Name, ReportTable));
Export(report, ReportName);
m_currentPageIndex = 0;
Print();
Dispose();
}
public void Dispose()
{
if (m_streams != null)
{
foreach (Stream stream in m_streams)
stream.Close();
m_streams = null;
}
}
}
}
调用运行方法的代码
Classes.DirectReportPrint drp = new Classes.DirectReportPrint();
drp.ReportTable = Classes.Class_Sales_Bill.GetBillDetails(this.saleObj.Row_ID);
drp.Run("POS.Reports.Rpt_Anil_Sale_Bill.rdlc", "DataSet1");
当我使用Visual Studio调试器执行它时,此代码很有效。但是,如果我发布项目,安装其设置然后尝试运行其exe (Weird Behaviour)
,则会失败。
如果我运行exe,它适用于我尝试打印的第一张发票。对于后续发票,我收到以下错误。
An error occurred during local report processing. Access to the Path 'c:\Users\Rpt_Anil_Sale_Bill_0.EMF' is denied.
此处Rpt_Anil_Sale_Bill
是我的RDLC文件的名称。
在进一步挖掘时,我发现exe代码在此路径中创建了一个中间EMF文件C:\Users\Nilesh\AppData\Local\Apps\2.0\BWQ6XD5A.DB0
如果我尝试打开此文件,则会收到以下错误:
需要帮助确定代码出了什么问题。
感谢任何帮助。谢谢!
答案 0 :(得分:3)
我使用了这段代码,对我来说效果非常好。
首先将此类添加到项目enter link description here
中然后使用以下代码直接打印到默认打印机:
LocalReport report = new LocalReport();
report.ReportEmbeddedResource = ReportSource;
report.DataSources.Add(myDataSource);
report.PrintToPrinter();