Tải Crystal Report

Trong các phiên bản Visual Studio thường có kèm theo công cụ Crystal Report để tạo các báo cáo (report) cho ứng dụng. Tuy nhiên, kể từ Visual 2010 thì công cụ Crystal Report đã bị xoá và để sử dụng chúng ta cần tải về và cài đặt.

Một cách phổ biến là dùng Google để tìm kiếm Crystal Report tương ứng với phiên bản Visual Studio. Ví dụ tôi đang dùng Visual Studio 2012 thì trong Google tôi sẽ gõ từ khoá tìm kiếm và sẽ chọn dòng liên kết đầu tiên (ô đỏ):

Khi nhấp vào dòng liên kết đầu tiên (ô đỏ) sẽ đến trang chứa liên kết đến nơi để tải Crystal Report:

Nhấp vào dòng liên kết (ô đỏ) để tải Crystal Report:

Cài đặt tập tin exe bằng cách nhấp đôi chuột trái vào tập tin vừa tải về:

Tạo một dự án web ASP.NET (VS 2012)

Chúng ta sẽ tạo một dự án ASP.NET (dùng VB) như sau:

  • Mở Visual Studio và chọn File > New > Web Site…
  • Chọn các tuỳ chọn và đặt tên cho dự án là Web_Report và nhấn OK:

Trong bài viết này chúng ta sẽ tìm hiểu các kiểu report sau:

  • Báo cáo đơn giản (simple report)
  • Báo cáo nhóm (group report)
  • Báo cáo biểu đồ (chart report)
  • Báo cáo con (sub report)
  • Báo cáo chéo (cross tab report)

Tôi sẽ minh hoạ với cơ sở dữ liệu (SQL Server) ngocminhtran với bảng Review có lược đồ và dữ liệu như sau:

Lược đồ

Dữ liệu

Tạo một report đơn giản

Đầu tiên chúng ta sẽ tạo một tập tin XSD như một nguồn dữ liệu rỗng để chúng ta có thể dùng với các kiểu dữ liệu. Cách tạo XSD như sau:

  • Tạo tập tin XSD bằng cách nhấn chuột phải vào Web_Report chọn Add > Add New Item > DataSet

  • Nhấn nút Add sẽ xuất hiện thông báo xác nhận bạn đặt tập tin XSD vừa tạo trong thư mục App_Code, nhấn Yes:

  • Một màn hình rỗng xuất hiện:

  • Thêm một bảng dữ liệu rỗng (data table) vào tập tin XSD vừa tạo bằng cách nhấp chuột phải vào vùng trống màu xám và chọn Add > Datatable:

  • Một bảng dữ liệu tên DataTable1 được thêm vào màn hình:

  • DataTable1 được thêm vào tập tin XSD. Bây giờ chúng ta sẽ tạo các cột cho bảng DataTable1 và lưu ý rằng, các cột nên đặt tên theo đúng tên và kiểu dữ liệu của các cột trong bảng Review ở trên và những cột được thêm trong bảng DataTable1 sẽ xuất hiện trong report. Để thêm cột Title vào bảng DataTable1 ta nhấp chuột phải vào DataTable1 chọn Add > Column:

  • Gõ tên cột là Title. Nhấp chuột phải vào bên trái cột Title và chọn Properties:

  • Trong hộp thoại Properties chúng ta tìm đến DataType và chọn kiểu dữ liệu tương ứng (mặc định là kiểu System.String). Trong bảng Review, cột Title có kiểu nchar(10) và tương đương System.String trong .NET Framework:

  • Tương tự tạo cột Summary (nvachar(50))

  • Tạo cột GenreId:

  • Kết quả

  • Lưu tất cả và đóng tập tin XSD. Bây giờ chúng ta thêm Crystal Report bằng cách kích chuột phải vào Web_Report trong cửa sổ Solution Explorer chọn Add > Add New Item > Crystal Report :

  • Khi nhấn nút Add để thêm Crystal Report sẽ xuất hiện hộp thoại Crystal Report Gallery như sau:

  • Nhấp OK sẽ xuất hiện hộp thoại và chúng ta sẽ chọn Project Data > ADO.NET DataSets > MyDataSample > DataTable1 như hình sau:

  • Nhấn vào nút > để thêm bảng DataTable1 vào khung Selected Tables bên phải:

  • Nhấn Finish. Kết quả

  • Các vùng trong một báo cáo:
    • Section1 (Report Header): các trường (hay cột) đặt trong vùng này được in một lần ở ngay đầu báo cáo.
    • Section2 (Page Header): các trường (hay cột) đặt trong vùng này được in tại đầu của mỗi trang mới.
    • Section3 (Details) : các trường (hay cột) đặt trong vùng này được in với mỗi hàng (hay bản ghi) mới.
    • Section4 (Report Footer)): các trường (hay cột) đặt trong vùng này được in một lần ở ngay cuối báo cáo.
    • Section5 (Page Footer) : các trường (hay cột) đặt trong vùng này được in ở ngay cuối mỗi trang mới.
  • Trong cửa sổ Field Explorer tìm đến Database Fields và mở rộng sẽ thấy DataTable1 và các cột vừa tạo:

  • Chọn và kéo lần lượt từng cột trong DataTable1 đặt sang vùng Section3 (Details) của report:

  • Như vậy report đã được thiết kế xong. Bây giờ chúng ta sẽ lấy dữ liệu từ database và kết buộc (bind) nó đến dataset và kết buộc dataset đến khung nhìn report (CrystalReportViewer). Tạo một trang aspx (Report.aspx) và từ thanh Toolbox chọn CrystalReportViewer từ Reporting:

  • Kết quả:

  • Nhấp đôi chuột vào trang aspx để đến khung viết code cho sự kiện Page_Load và thêm code như sau:

Mã VB


Imports CrystalDecisions.CrystalReports.Engine

Imports CrystalDecisions.Shared

Imports System.Data

Imports System.Data.SqlClient

Imports System.Configuration

Imports System.IO

Partial Class Report

Inherits System.Web.UI.Page

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

Dim rptDoc As ReportDocument = New ReportDocument()

Dim ds As MyDataSample = New MyDataSample() ' tập tin .xsd

Dim dt As DataTable = New DataTable()

' Đặt tên cho datatable

dt.TableName = "Crystal Report Example"

dt = getAllGeres() 'Gọi hàm getAllGenres

ds.Tables(0).Merge(dt)

' Lấy đường dẫn tập tin crystal report (CrystalReport.rpt)

rptDoc.Load(Server.MapPath("CrystalReport.rpt"))

'gán dataset đến report view

rptDoc.SetDataSource(ds)

CrystalReportViewer1.ReportSource = rptDoc

CrystalReportViewer1.DisplayToolbar = True

End Sub

Public Function getAllGeres() As DataTable

Dim connectionString As String

connectionString = "Data Source=.\SQLEXPRESS;Initial Catalog=ngocminhtran;Integrated Security=True;"

Dim Con As SqlConnection = New SqlConnection(connectionString)

Dim cmd As SqlCommand = New SqlCommand()

Dim ds As DataSet = Nothing

Dim adapter As SqlDataAdapter

Try

Con.Open()

cmd.CommandText = "SELECT * FROM Review"

cmd.CommandType = CommandType.Text

cmd.Connection = Con

ds = New DataSet()

adapter = New SqlDataAdapter(cmd)

adapter.Fill(ds, "Review")

Catch ex As Exception

Throw New Exception(ex.Message)

Finally

cmd.Dispose()

If Con.State <> ConnectionState.Closed Then

Con.Close()

End If

End Try

Return ds.Tables(0)

End Function

End Class

Mã C#


using System.Data;

using CrystalDecisions.CrystalReports.Engine;

using CrystalDecisions.Shared;

using System.Data.SqlClient;

using System.Configuration;

using System.IO;

partial class Report : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

ReportDocument rptDoc = new ReportDocument();

MyDataSample ds = new MyDataSample();

// tập tin .xsd

DataTable dt = new DataTable();

// Đặt tên cho datatable

dt.TableName = "Crystal Report Example";

dt = getAllGeres();

//Gọi hàm getAllGenres

ds.Tables[0].Merge(dt);

// Lấy đường dẫn tập tin crystal report (CrystalReport.rpt)

rptDoc.Load(Server.MapPath("CrystalReport.rpt"));

//gán dataset đến report view

rptDoc.SetDataSource(ds);

CrystalReportViewer1.ReportSource = rptDoc;

CrystalReportViewer1.DisplayToolbar = true;

}

public DataTable getAllGeres()

{

string connectionString = null;

connectionString = "Data Source=.\\SQLEXPRESS;Initial Catalog=ngocminhtran;Integrated Security=True;";

SqlConnection Con = new SqlConnection(connectionString);

SqlCommand cmd = new SqlCommand();

DataSet ds = null;

SqlDataAdapter adapter = default(SqlDataAdapter);

try {

Con.Open();

cmd.CommandText = "SELECT * FROM Review";

cmd.CommandType = CommandType.Text;

cmd.Connection = Con;

ds = new DataSet();

adapter = new SqlDataAdapter(cmd);

adapter.Fill(ds, "Review");

} catch (Exception ex) {

throw new Exception(ex.Message);

} finally {

cmd.Dispose();

if (Con.State != ConnectionState.Closed) {

Con.Close();

}

}

return ds.Tables[0];

}

}

  • Lưu và thực thi trang web trên browser (Chrome).
  • Khi mới thực hiện lần đầu có thể xảy ra các trường hợp không như mong đợi, cụ thể:
    • Một số biểu tượng trên Report không hiển thị như trang ở trên.
    • Không xuất hiện Report (trang trống).
  • Nguyên nhân của các tình trạng này là do chúng ta thiếu các tập tin từ thư mục aspnet_client để giúp thực thi report trên các trình duyệt. Giải pháp là sao chép thư mục aspnet_client từ C:\inetpub\wwwroot và đặt trong thư mục gốc chứa dự án web của chúng ta:

  • Nếu thực hiện điều này thì kết quả sẽ như sau:

Tạo report nhóm (group report)

Trong báo cáo chúng ta thường gặp trường hợp nhóm các thông tin liên quan nhau, ví dụ trong bảng Review cùng một GenreId 100 có hai TitleTitle 01 và Title 04, chúng ta có thể nhóm các Title theo GenreId.

  • Tạo một Crystal Report mới tên GroupCrystalReport.rpt và chọn DataTable1 giống như trên:

  • Kích chuột phải vào report chọn Report > Group Experts:

  • Hiện hộp thoại Group Expert

  • Chúng ta sẽ nhóm theo GenreIdTitle bằng cách chọn GenreId trước và nhấn nút > sau đó chọn Title và nhấn nút >, kết quả:

  • Nhấn OK. Lần này Crystal Report sẽ xuất hiện thêm GroupHeaderSection1, GroupHeaderSection2, GroupFooterSection1, GroupFooterSection2:

  • Group #1 Name tham chiếu đến GenreIdGroup #2 Name tham chiếu đến Title. Chúng ta có thể thực hiện thêm vài thao tác nhóm tại GroupFooterSection nếu cần. Lưu tất cả.
  • Trong code của sự kiện Load, thay đổi đường dẫn đến GroupCrystalReport.rpt thay vì CrystalReport.rpt:

Mã VB


rptDoc.Load(Server.MapPath("GroupCrystalReport.rpt"))

Mã C#


rptDoc.Load(Server.MapPath("GroupCrystalReport.rpt"));

  • Thực thi trang và kết quả:

  • Chúng ta có thể điều chỉnh các cột GenreIdTitle trong report để nhìn có tính cấu trúc hơn, ví dụ chúng ta thay đổi các cột Title trong GroupCrystalReport như sau:

  • Lưu và thực thi lại trang:

Tạo report biểu đồ (chart report)

  • Biểu đồ là công cụ trực quan rất mạnh mẽ trong các báo cáo. Để tạo biểu đồ trong báo cáo, chúng ta tạo một Crystal Report mới (giả sử là ChartReport.rpt). Kế tiếp nhấp chuột phải lên vùng thiết kế của ChartReport.rpt chọn Insert > Chart:

  • Sẽ không có gì xuất hiện nhưng con trỏ chuột sẽ có một hình chữ nhật:

  • Chúng ta chỉ cần nhấp chuột lên Section1 sẽ xuất hiện:

  • Chúng ta có thể chọn kiểu biểu đồ trong Type, chọn Vertical (đứng) hay Horizontal (ngang), chọn Use Depth effect nếu muốn có hiệu ứng chiều sâu.
  • Di chuyển đến tab Data

  • Ở đây chúng ta có thể chọn các cột để chuyển qua khung On change of (ví dụ là GenreId)Show value(s) (ví dụ là Title)OK

  • Kết quả:

  • Trong code của sự kiện Load, thay đổi đường dẫn đến ChartReport.rpt:

Mã VB


rptDoc.Load(Server.MapPath("ChartReport.rpt"))

Mã C#


rptDoc.Load(Server.MapPath("ChartReport.rpt"));

  • Thực thi trang và kết quả:

Tạo báo cáo trong báo cáo (sub report)

Crystal Report cho phép tạo báo cáo trong báo cáo, một đặc trưng được gọi là subreport.

  • Để hiểu hơn chúng ta tạo một Crystal Report mới tên SubReport.rpt. Nhấp chuột phải lên vùng thiết kế của SubReport.rpt và chọn Report > Group Expert và chỉ chọn GenreId

  • Kết quả:

  • Nhấp chuột phải lên vùng Section 3 (Details)(vùng màu trắng) chọn Insert > Subreport:

  • Sẽ xuất hiện con trỏ chuột có hình chữ nhật, nhấp chuột vào tiêu đề Section 3 (Details) sẽ xuất hiện:

  • Chúng ta có thể chọn một Crystal Report trong dự án hay có sẵn bằng cách chọn Choose a Crystal Report in project hay Choose an existing report hoặc có thể tạo một subreport bằng Report Wizard bằng cách chọn Create a subreport with the Report Wizard, gõ tên report vào ô New report name (ví dụ SomeDetails) và nhấn nút Report Wizard. Chúng ta chọn DataTable1 và nhấn nút >Finish. Nhấp OK. Một sub report được thêm vào vùng section 3:

  • Chúng ta có thể chỉnh sửa lại SubReport bằng cách nhấp chuột phải vào SubReport chọn Edit Subreport sẽ chuyển đến vùng thiết kế của sub report:

  • Chúng ta có thể chuyển đổi qua lại giữa report chính và report con bằng cách nhấp chuột vào các nút Main Report hay SubReport. Lúc này Crystal Report đã tạo ra một tập tin rpt riêng cho sub report nhưng nó ẩn trong report chính nên chúng ta không thể thấy. Thêm TitleSummary đến sub report như sau:

  • Lưu và thực thi trang (nhớ thay đổi SubReport.rpt trong mã của sự kiện Load). Kết quả:

Tạo cross tab report

  • Tạo một tập tin Crystal Report tên CrossTabReport.rpt. Lần này chúng ta thêm report vào Section 1 bằng cách nhấp chuột phải vào vùng trống của Section 1 chọn Insert > Cross-Tab:

  • Trong hộp thoại Cross Tab Expert chọn hàng và cột như sau:

  • Nhấp OK. Thực thi trang

Lời kết

Trên đây là một số kiểu report hay gặp khi sử dụng công cụ Crystal Report và để thành thạo hơn chúng ta cần tìm hiểu thêm các nguồn tham khảo khác trên Internet.