Search code examples
wpfvb.netcrystal-reports

How to integrate Crystal Reports in WPF?


I'm working on a WPF (VB) project where I need to link the existing crystal report to the WPF application. The user will enter a job number from my WPF application; after that I need to run the query (select * from JobHeader where Jobnumber=@userjobnumber); and then I need to call the crystal report that will have all the detailed information of that JobNumber.

Also, I've a sample WPF application ready from where user will enter the jobnumber. I've the crystal report ready as well. Stuck with integrating crystal report with WPF. Can somebody please give help me? Stuck with this issue for long time and approaching deadline. Please help.

Thanks

Here is my VBCode:

Imports System.Globalization
Imports System.Drawing.Printing
Imports System.Drawing
Imports System.Data
Imports System.Data.SqlClient



Class MainWindow

Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    AddHandler printDocument1.PrintPage, AddressOf printDocument1_PrintPage
End Sub

'Declaration  the  global  variables 
Private paperSize As New PaperSize("papersize", 300, 500)
'set the paper size 
Private totalnumber As Integer = 0
'this is for total number of items of the list or array
Private itemperpage As Integer = 0
'this is for no of item per page 
Private printDocument1 As New PrintDocument()
Private printDialog1 As New System.Windows.Forms.PrintDialog()
Private DefaultFont As New Font("Calibri", 20)
Public StrConn As String = "Data Source=it-  12\localAv01;Database=AvTest01;Uid=sa;Pwd=test123"
Dim QueryStr = "Select * from JobHeader where JobNumber="
Dim ConnStr = StrConnAvanti
Dim dTable As DataTable = New DataTable()




Private Sub Button_Click(sender As Object, e As RoutedEventArgs)

    If txtStart.Text.Trim.Length > 0 Then
        itemperpage = 1
        totalnumber = txtStart.Text.Replace("J", "")
        printDialog1.Document = printDocument1
        printDocument1.DefaultPageSettings.PaperSize = paperSize
        printDialog1.ShowDialog()

        'printDocument1.PrinterSettings.PrinterName = "";
        printDocument1.Print()
    Else
        MessageBox.Show("Invalid number")
    End If
End Sub

Private Function CheckNumber(str As String)
    Dim Num As Double
    Return Double.TryParse(str, Num)
End Function

Private Sub printDocument1_PrintPage(sender As Object, e As System.Drawing.Printing.PrintPageEventArgs)
    Dim currentY As Single = 10

    While totalnumber <= txtStart.Text.Replace("J", "")
        ' check the number of items 

        e.Graphics.DrawString("J" + totalnumber.ToString("000000", CultureInfo.InvariantCulture), DefaultFont, System.Drawing.Brushes.Black, 50, currentY)


        'print each item
        currentY += 20
        ' set a gap between every item
        totalnumber += 1
        'increment count by 1
        If itemperpage < 1 Then
            ' check whether  the number of item(per page) is more than 1 or not
            itemperpage += 1
            ' increment itemperpage by 1
            ' set the HasMorePages property to false , so that no other page will not be added 
            e.HasMorePages = False
        Else

            ' if the number of item(per page) is more than 1 then add one page 
            itemperpage = 1
            'initiate itemperpage to 0 . 
            If totalnumber <= Convert.ToInt32(txtStart.Text.Replace("J", "")) Then
                e.HasMorePages = True
            End If
            'e.HasMorePages raised the PrintPage event once per page .           
            'It will call PrintPage event again
            Return
        End If
    End While
End Sub
End Class

Solution

  • I used WPF/C# to integrate Crystal Reports, but it should be very similar. Make sure you installed the developer edition so you can add the references you need for Crystal/SAP. First, i made a Report Viewer window:

    <Window x:Class="Bill.Views.Reports.ReportView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStartupLocation="CenterOwner"
        xmlns:Viewer="clr-namespace:SAPBusinessObjects.WPF.Viewer;assembly=SAPBusinessObjects.WPF.Viewer"
        Title="ReportView" >
    <Grid>
        <Viewer:CrystalReportsViewer Name="ReportViewer"/>
    </Grid>
    

    Next, is the code-behind:

    using System;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using Bill.Constants;
    using Bill.Models.Reports;
    using CrystalDecisions.CrystalReports.Engine;
    using CrystalDecisions.Shared;
    
    namespace Bill.Views.Reports
    {
        /// <summary>
        /// Interaction logic for ReportView.xaml
        /// </summary>
        public partial class ReportView : Window
        {
            public ReportView(Report report)
            {
                InitializeComponent();
    
                ReportViewer.Owner = Window.GetWindow(this);  //added to fix null parameter window bug in Crytal report 
    
                if (Application.Current.MainWindow.IsLoaded)
                {
                    this.Owner = Application.Current.MainWindow;
                }
    
                ShowReport(report.FileInfo.FullName);
            }
    
            /// <summary>
            /// Show the selected report
            /// </summary>
            /// <param name="reportPath"></param>
            private void ShowReport(string reportPath)
            {
                ReportDocument report = new ReportDocument();
    
                if (!String.IsNullOrEmpty(reportPath))
                {
                    TableLogOnInfos crtableLogoninfos = new TableLogOnInfos();
                    TableLogOnInfo crtableLogoninfo = new TableLogOnInfo();
                    ConnectionInfo crConnectionInfo = new ConnectionInfo();
                    Tables CrTables;
    
                    report.Load(reportPath);
    
                    SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(ConnectionStrings.CurrentConnection.ConnectionString);  //from config.xml
                    crConnectionInfo.ServerName = builder.DataSource;
                    crConnectionInfo.DatabaseName = builder.InitialCatalog;
                    crConnectionInfo.IntegratedSecurity = true;
    
                    CrTables = report.Database.Tables;
                    foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in CrTables)
                    {
                        crtableLogoninfo = CrTable.LogOnInfo;
                        crtableLogoninfo.ConnectionInfo = crConnectionInfo;
                        CrTable.ApplyLogOnInfo(crtableLogoninfo);
                    }
    
                    if (reportPath.Contains("BillingSummary"))
                    {
                        //report.SetParameterValue("prmBillingCycle", 10);
    
                        report.SetParameterValue("@BillingTypeID", null);
                        report.SetParameterValue("@BillingModelID", null);
    
                        report.SetParameterValue("@InvoiceID", null, report.Subreports[1].Name.ToString());
                        report.SetParameterValue("@InvoiceID", null, report.Subreports[2].Name.ToString());
    
                        report.SetParameterValue("@ForGrid", null, report.Subreports[1].Name.ToString());
                        report.SetParameterValue("@ForGrid", null, report.Subreports[2].Name.ToString());
                    }
    
                    ReportViewer.ViewerCore.ReportSource = report;
                    ReportViewer.ViewerCore.EnableDrillDown = false;
                    ReportViewer.ToggleSidePanel = SAPBusinessObjects.WPF.Viewer.Constants.SidePanelKind.None;
                    ReportViewer.ShowLogo = false;
                    ReportViewer.ShowToggleSidePanelButton = false;
                    ReportViewer.ShowRefreshButton = false;
    
                    //report.Refresh();
                }
            }
        }
    }
    

    Also, here is a link that helped me get started: http://scn.sap.com/docs/DOC-54328