How to print the report directly without previewing (report viewer) using c# windows application

Hi,
Currently, we are using crystal report to all of our reporting applications, but since I/users have encountered some issues about CR's speed to load only a simple report, maybe it is now time for us to adopt a new reporting environment in which I think SSRS
can fill this problem.
To start with, I have here a sample code, that uses the crystal report to print the report directly without previewing:
csCashInvoiceCal csCashCal; --Crystal report name .rpt
dsCsReceipt dsCs; --created dataset
DataTable u;
DataRow s;
private System.Drawing.Printing.PrintDocument printDocument1;
private System.Windows.Forms.PrintDialog printDialog1;
ParameterValues paramValue;
ParameterDiscreteValue discreteValue;
ParameterFieldDefinition fieldDefinition;
private void btnPrint_Click(object sender, EventArgs e)
this.Cursor = Cursors.WaitCursor;
loadReceipt2();
print2();
csCashCal.Close();
this.Cursor = Cursors.Default;
private void loadReceipt2()
dsCs = new dsCsReceipt(); --created dataset
u = dsCs.Tables.Add("DtCsReceipt");
u.Columns.Add("Qty", Type.GetType("System.String"));
u.Columns.Add("UOM", Type.GetType("System.String"));
u.Columns.Add("Description", Type.GetType("System.String"));
u.Columns.Add("UnitPrice", Type.GetType("System.String"));
u.Columns.Add("Discount", Type.GetType("System.String"));
u.Columns.Add("Amount", Type.GetType("System.String"));
try
for (int i = 0; i < dgvDesc.Rows.Count - 1; i++)
s = u.NewRow(); double.TryParse(dgvDesc.Rows[i].Cells[Discount2.Name].Value.ToString(), out discount);
s["Qty"] = double.Parse(dgvDesc.Rows[i].Cells[Qty.Name].Value.ToString());
s["UOM"] = dgvDesc.Rows[i].Cells[Uom2.Name].Value.ToString();
s["Description"] = invcode + dgvDesc.Rows[i].Cells[Description.Name].Value.ToString();
s["UnitPrice"] = dgvDesc.Rows[i].Cells[UnitPrice.Name].Value.ToString();
if (discount != 0)
s["Discount"] = "(" + string.Format("{0:0.##}", discount) + "%)";
else
s["Discount"] = "";
s["Amount"] = dgvDesc.Rows[i].Cells[Amount2.Name].Value.ToString();
u.Rows.Add(s);
catch (Exception) { }
csCashCal = new csCashInvoiceCal();
csCashCal.SetDataSource(dsCs.Tables[1]);
//csCashCal.Refresh();
loadParameter2();
private void loadParameter2()
ParameterFieldDefinitions paramFieldDefinitions;
paramValue = new ParameterValues();
discreteValue = new ParameterDiscreteValue();
paramFieldDefinitions = csCashCal.DataDefinition.ParameterFields;
discreteValue.Value = date;
fieldDefinition = paramFieldDefinitions["Date"];
commonParam();
discreteValue.Value = txtcsno.Text;
fieldDefinition = paramFieldDefinitions["InvoiceNo"];
commonParam();
discreteValue.Value = txtNameTo.Text;
fieldDefinition = paramFieldDefinitions["CustomerName"];
commonParam();
discreteValue.Value = txtAdd.Text;
fieldDefinition = paramFieldDefinitions["CustomerAddress"];
commonParam();
------other parameters----
private void commonParam()
paramValue.Clear();
paramValue.Add(discreteValue);
fieldDefinition.ApplyCurrentValues(paramValue);
private void print2()
using (printDocument1 = new System.Drawing.Printing.PrintDocument())
using (this.printDialog1 = new PrintDialog())
//this.printDialog1.UseEXDialog = true;
this.printDialog1.Document = this.printDocument1;
DialogResult dr = this.printDialog1.ShowDialog();
if (dr == DialogResult.OK)
int nCopy = this.printDocument1.PrinterSettings.Copies;
int sPage = this.printDocument1.PrinterSettings.FromPage;
int ePage = this.printDocument1.PrinterSettings.ToPage;
string PrinterName = this.printDocument1.PrinterSettings.PrinterName;
try
csCashCal.PrintOptions.PrinterName = PrinterName;
csCashCal.PrintToPrinter(nCopy, false, sPage, ePage);
printcount++;
//saveCountPrint();
catch (Exception err)
MessageBox.Show(err.ToString());
This is only a simple sales receipt application that uses dgv and textboxes to push its data to dataset to the crystal report, a simple one but there are instances that it is very slow.
But I'm having trouble implementing this using SSRS, since I'm only new to this one, wherein I created the report using report wizard, with two button options inside the form for print preview or direct print selection. Actually, it is very easy to implement
with print preview because it uses reportviewer. My problem is that how can I print the report directly without using a reportviewer?
So here is my code so far which I don't know what's next:
private void button2_Click(object sender, EventArgs e)
this.Cursor = Cursors.WaitCursor;
loadReceipt3();
//print3();
this.Cursor = Cursors.Default;
ReportParameter[] parameter = new ReportParameter[11];
private void loadParameter3()
parameter[0] = new ReportParameter("InvoiceNo", txtcsno.Text);
parameter[1] = new ReportParameter("Date", date);
parameter[2] = new ReportParameter("CustomerTin", txtTin.Text);
parameter[3] = new ReportParameter("CustomerName", txtNameTo.Text);
parameter[4] = new ReportParameter("CustomerAddress", txtAdd.Text);
parameter[5] = new ReportParameter("Agent", agent);
parameter[6] = new ReportParameter("Discount", "Discount: ");
parameter[7] = new ReportParameter("TotalDiscount", lblDiscount.Text + "%");
parameter[8] = new ReportParameter("TotalSales", rdtotal);
parameter[9] = new ReportParameter("Tax", rdtax);
parameter[10] = new ReportParameter("TotalAmount", rdnet);
private void loadReceipt3()
DataSet dsrs = new DataSet();
DataTable dtrs = new DataTable();
DataRow drs;
dtrs.Columns.Add("Qty", Type.GetType("System.String"));
dtrs.Columns.Add("UOM", Type.GetType("System.String"));
dtrs.Columns.Add("Description", Type.GetType("System.String"));
dtrs.Columns.Add("UnitPrice", Type.GetType("System.String"));
dtrs.Columns.Add("Discount", Type.GetType("System.String"));
dtrs.Columns.Add("Amount", Type.GetType("System.String"));
try
for (int i = 0; i < dgvDesc.Rows.Count - 1; i++)
drs = dtrs.NewRow();
drs["Qty"] = double.Parse(dgvDesc.Rows[i].Cells[Qty.Name].Value.ToString());
drs["UOM"] = dgvDesc.Rows[i].Cells[Uom2.Name].Value.ToString();
drs["Description"] = invcode + dgvDesc.Rows[i].Cells[Description.Name].Value.ToString();
drs["UnitPrice"] = dgvDesc.Rows[i].Cells[UnitPrice.Name].Value.ToString();
if (discount != 0)
drs["Discount"] = "(" + string.Format("{0:0.##}", discount) + "%)";
else
drs["Discount"] = "";
drs["Amount"] = dgvDesc.Rows[i].Cells[Amount2.Name].Value.ToString();
dtrs.Rows.Add(s);
catch (Exception) { }
int addtlRow = 7;
if (addtlRow > (count - 1))
addtlRow = addtlRow - (count - 1);
for (int i = 0; i < addtlRow; i++)
dtrs.Rows.Add();
loadParameter3();
LocalReport localreport = new LocalReport();
localreport.SetParameters(parameter);
localreport.DataSources.Clear();
localreport.DataSources.Add(new ReportDataSource("dsSalesReceiptSsrs", dtrs));
localreport.Refresh();
//what's next....
So what's next after local..refresh()? Actually, I have googled a lot but I didn't found the exact solution that I'm looking for which confuses me a lot.
Anyway I'm using VS 2010 with sql server 2012 express.
You're help will be greatly appreciated.
Thank you,
Hardz
Advertisement
Reply

After some further studies with ReportViewer controls and with the use of this tutorial @ : http://msdn.microsoft.com/en-us/library/ms252091.aspx, which helps me a lot on how to print a report without using a report viewer, I found out what is missing
with my code above and helps solve my question.
Here's the continuation of the code above:
private void loadReceipt3()
loadParameter3();
LocalReport localreport = new LocalReport();
localreport.ReportPath = @"..\..\SsrsCashReceipt.rdlc";
localreport.SetParameters(parameter);
localreport.DataSources.Clear();
localreport.DataSources.Add(new ReportDataSource("dsSalesReceiptSsrs", dtrs));
Export(localreport);
print4();
private IList<Stream> m_streams;
private int m_currentPageIndex;
private void Export(LocalReport report)
string 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>";
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 print4()
if (m_streams == null || m_streams.Count == 0)
throw new Exception("Error: no stream to print.");
PrintDocument printDoc = new PrintDocument();
PrintDialog printDlg = new PrintDialog();
printDlg.Document = printDoc;
DialogResult dr = printDlg.ShowDialog();
if (dr == DialogResult.OK)
if (!printDoc.PrinterSettings.IsValid)
throw new Exception("Error: cannot find the default printer.");
else
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
m_currentPageIndex = 0;
printDoc.Print();
Dispose();
public void Dispose()
if (m_streams != null)
foreach (Stream stream in m_streams)
stream.Close();
m_streams = null;
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;
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);
Thank you very much for this wonderful tutorial. :)