【问题标题】:Print Crystal Report Directly in ASP.NET C#在 ASP.NET C# 中直接打印水晶报表
【发布时间】:2015-06-11 18:41:07
【问题描述】:

我正在使用 SQL Server 存储过程在 Crystal Report 中填充数据。我能够使用 CR 中的公式传递和格式化每一列的参数来实现我想要的打印输出。

在打印报表时,通常的过程是它会在 Crystal Report Viewer 中预览创建/生成的输出,然后有打印、导出选项,它将首先将报表转换为 PDF 以进行打印功能

我想要的是当我点击打印按钮时,它会自动进入打印程序。

我被引导到此链接以获取答案How to print crystal report directly to a client machine using C# Asp.net

using oReportDocument.PrintToPrinter(1,true,0,0); 

代码,其他人也建议在页面初始化中填充数据集,但我似乎不知道该怎么做。

这是我当前工作的代码(通常的打印过程,它将首先引导您进入 Crystal Report 预览。

public partial class Report_MonthlySalesReportPrint : System.Web.UI.Page
{
    SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
    ReportDocument report = new ReportDocument();

    protected void Page_Load(object sender, EventArgs e)
    {
        con.Open();

        //Parameters to be passed as needed in formulas in Report
        string RP = Session["RP"].ToString();
        DateTime cms = Convert.ToDateTime(Session["CurrentMonthStart"].ToString());
        string Loc = Session["Location"].ToString();
        string MonthCurrent = Session["MonthCurrent"].ToString();
        string YearCurrent = Session["YearCurrent"].ToString();
        string MonthPrevious = Session["MonthPrevious"].ToString();
        string YearPrevious = Session["YearPrevious"].ToString();
        string MonthLastYear = Session["MonthLastYear"].ToString();
        string YearLastYear = Session["YearLastYear"].ToString();

        report.Load(Server.MapPath("MSRC.rpt"));

        CrystalReportViewer1.ReportSource = report;
        CrystalReportViewer1.ReuseParameterValuesOnRefresh = true;
        CrystalReportViewer1.DataBind();

        report.SetParameterValue(0, MonthLastYear);
        report.SetParameterValue(1, MonthCurrent);
        report.SetParameterValue(2, MonthPrevious);
        report.SetParameterValue(3, RP);
        report.SetParameterValue(4, Loc);
        report.SetParameterValue(5, cms);
        report.SetParameterValue(6, YearCurrent);
        report.SetParameterValue(7, YearPrevious);
        report.SetParameterValue(8, YearLastYear);

        report.PrintToPrinter(1, true, 0, 0);
        con.Close();
    }
}

更新:

我只是需要这个来更新以澄清以下接受的答案仅在服务器端有效。这意味着当用户远程访问服务器时,代码将不起作用。

【问题讨论】:

    标签: c# asp.net crystal-reports


    【解决方案1】:
           using System.Drawing.Printing;
           using Crystal Decisions.CrystalReports.Engine;
           using Crystal Decisions.Shared;
           protected void Page_Load(object sender, EventArgs e)
           {
             void();
           }
           public void()
           {
             try
            {
             ReportDocument crystalReport = new ReportDocument();
             crystalReport.Load(Server.MapPath("~/CrystalReport2.rpt"));
             DataSet dsCustomers = GetData("select * from visitor_details where  id ='" + Session["sessionvid"] + "' and  plant ='" + Session["sessionplant"] + "'");
    
             DataTable dataTable = dsCustomers.Tables[0];   crystalReport.Database.Tables["visitor_details"].SetDataSource((DataTable)dataTable);
              CrystalReportViewer2.ReportSource = crystalReport;
              CrystalReportViewer2.Zoom(100);
              //crystalReportViewer1.ExportReport() ;
              CrystalReportViewer2.RefreshReport();
              crystalReport.PrintOptions.PrinterName = GetDefaultPrinter();
              crystalReport.PrintToPrinter(1, false, 0, 0);
            }
            catch
            {
                Response.Write("<script LANGUAGE='JavaScript' >alert('connect printer settings')</script>");
            }
    

    }

    【讨论】:

    • 嗨@balajibran,根据我发布的内容,我们几乎拥有相同的代码。唯一的区别是我不使用数据集和数据表。我按照您的建议放置了 crystalReport.PrintToPrinter(1, false, 0, 0);仅在我当前的代码中,但没有任何改变,它仍在预览到水晶报表查看器。
    • 好消息,这已经为我工作了,前一段时间唯一的问题是我没有连接到正确的打印机。但是,我还有一些疑问,如何在打印机对话框中设置它在立即打印之前首先显示的位置,我的意思是我需要它来设置纸张尺寸并通常通知正在打印的用户。
    • 我投了赞成票,因为它回答了问题,但是我想要的是应该首先弹出一个 PRINT DIALOG 以选择可用的打印机,因为使用我们使用的代码,它实际上会打印报告直接和立即。我需要一个打印对话框以获得更灵活的打印选项。我怎样才能做到这一点?谢谢
    【解决方案2】:

    这对我有用。如果需要,您可以创建自己的PageSettings,否则只需使用 emtpy。

    如果要打开打印对话框,只需使用PrintDialog

    using System.Windows.Forms;
    
    //...
    
    ReportClass report = new ReportClass();
    report.FileName = @"C:/Layout.rpt";
    report.Load();
    report.SetDataSource(YourSource);
    
    PrinterSettings settings = new PrinterSettings();
    
    PrintDialog pdialog = new PrintDialog();
    if (pdialog.ShowDialog() == DialogResult.OK)
    {
        settings = pdialog.PrinterSettings;
    }
    
    report.PrintToPrinter(settings, new PageSettings() { }, false);
    

    【讨论】:

    • 嗨@DionV。在打印机名称上,我应该输入实际的完整打印机名称吗?还有datasourcename,如果我不使用数据集并且我的数据源直接来自存储过程,我该怎么办?
    • @rickyProgrammer 是的,完整的打印机名称。 SetDataSource 方法也接受 DataTable 甚至是 IEnumerable。如果您的数据来自存储过程,您可能会收到DataTable
    • 我已经使用 CrystalReport.PrintToPrinter(1, false, 0, 0); 解决了问题我只是将它包含在我上面发布的代码中,它直接打印页面,但是我想要的是首先弹出一个打印对话框来选择打印机。
    • 我正在尝试代码,但 PrintDialog 是红线。我是否缺少类型或命名空间声明?我已经使用 System.Drawing.Printing 将这两个作为我的命名空间;使用 System.Drawing;
    • @ricktProgrammer 是的,你需要 System.Windows.Forms。
    【解决方案3】:

    1.客户端打印

    这是在基于 Web 的应用程序中打印的最理想方法,因为大多数用户肯定会远程访问服务器。

    将此 javascript 代码放在水晶报表查看器所在的 .aspx 页面的 head 标记中。

         <script type="text/javascript">
    
    
                    function Print() {
                          var dvReport = document.getElementById("dvReport");
                          var frame1 = dvReport.getElementsByTagName("iframe")[0];
                          if (navigator.appName.indexOf("Internet Explorer") != -1) {
                              frame1.name = frame1.id;
                              window.frames[frame1.id].focus();
                              window.frames[frame1.id].print();
                          }
                          else {
                              var frameDoc = frame1.contentWindow ? frame1.contentWindow : frame1.contentDocument.document ? frame1.contentDocument.document : frame1.contentDocument;
                              frameDoc.print();
                          }
                      }
                </script>
    

    同一个页面,在body标签里放这个

      <body>
            <form id="form1" runat="server">
            <asp:Button ID="btnPrint" runat="server" Text="Print Directly" OnClientClick="Print()"></asp:Button>
    
              <div id="dvReport">
                <CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server" AutoDataBind="true" ToolPanelView="None" EnableDatabaseLogonPrompt="false"  />
    
    
              </div>
            </form>
        </body>
    

    -- 记下那里的按钮。它应该在包含水晶报表查看器的 div 之外。这肯定会奏效。请参阅有关此方法的完整讨论:http://www.aspsnippets.com/Articles/Print-Crystal-Report-on-Client-Side-on-Button-Click-using-JavaScript-in-ASPNet.aspx


    2。服务器端打印

    这里建议最多的答案是 printToPrinter() 函数。此方法是在服务器端完成的,因此,当您远程访问基于 Web 的应用程序/网站的服务器时,它会受到限制,除非客户端可以映射或访问服务器打印机。


    请阅读此内容以获取更多信息:http://aspalliance.com/509_Automatically_Printing_Crystal_Reports_in_ASPNET.3

    【讨论】:

      【解决方案4】:
                  CrystalReportSaleSlip _CrystalReportSaleSlip = new CrystalReportSaleSlip();
                  _CrystalReportSaleSlip.SetDataSource(dtReport);
      
                  _CrystalReportSaleSlip.PrintOptions.PrinterName = "Hp Laserjet M1522 MFP Series PCL 6";
                  _CrystalReportSaleSlip.PrintToPrinter(1, false, 0, 0);
                  crystalReportViewer1.Refresh(); 
      

      【讨论】:

        【解决方案5】:

        只有在服务器中配置了打印机时,PrintToPrinter 才能工作。从客户端,这可能不起作用,因为打印机可能未列出

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多