Khái niệm trường, tham số và biến số trong JasperReport
NỘI DUNG BÀI VIẾT
Trong một report, có ba loại đối tượng có thể lưu trữ giá trị:
- Field – Trường
- Parameter – Tham số
- Variable – Biến số
JasperSoft Studio sử dụng các đối tượng này trong truy vấn nguồn dữ liệu, theo thứ tự các đối tượng này được khai báo với dạng trìu tượng tương tự như một lớp trong Java như String, Double… Sau khi chúng được khai báo trong quá trình thiết kế báo cáo, các đối tượng này có thể thay đổi, cập nhật lại giá trị trong quá trình xử lý sinh báo cáo.
1. Trường
Datasource cung cấp một tập hợp là một chuỗi các trường, từ đó tạo ra báo cáo, nó giống như kết quả của một câu truy vấn SQL. JasperSoft Studio hiển thị các trường trong nút Fields ở cửa sổ Outline. Để tạo một trường mới, bạn chỉ việc nhấp chuột phải vào nút Fields và chọn Create Field. Một trường mới sẽ ở dạng undefined trong cửa sổ Properties và bạn có thể nhập các thông tin về trường mới như tên trường, mô tả, dạng dữ liệu của trường. Chúng ta có thể định nghĩa một tập các cặp thuộc tính (tên/giá trị) cho mỗi trường. Các thuộc tính cá nhân này không thể sinh ra bởi JasperReport nhưng chúng có thể được sử dụng bởi các ứng dụng ngoài có tích hợp JasperReport. JasperSoft Studio xác định giá trị của một trường dựa trên data source, ví dụ khi sử dụng một truy vấn SQL, JasperSoft Studio giả sử rằng tên của trường là trùng khớp với tên các trường trong tập kết quả truy vấn. Một chú ý là dạng dữ liệu của trường phải khới với dạng dữ liệu trong data source. Trong mỗi biểu thức của báo cáo, JasperSoft Studio xác định một đối tượng trường bằng cú pháp
$F{<tên_trường>}</tên_trường>
Code language: HTML, XML (xml)
Chú ý, khi sử dụng một biểu thức có tham chiếu đến trường cần chú ý giá trị của trường có thể là null, bởi vậy bạn cần kiểm tra điều kiện trước khi thực hiện các công việc khác, ví dụ là một lời gọi hàm như ví dụ dưới:
($F{productPrice} != null) ? $F{productPrice}.getTotalAmount() : null
Code language: PHP (php)
Trong một vài trường hợp, một trường có thể là một đối tượng phức tạp kiểu như JavaBean, nó không đơn thuần là các giá trị kiểu như String, Integer… một mẹo để chuyển đổi các đối tượng này sang dạng String bằng cách nối giá trị của nó với một chuỗi rỗng:
$F{myField} + ""
Code language: PHP (php)
1.1 Đăng ký trường từ truy vấn SQL
Một câu truy vấn SQL là cách dễ nhất để đưa dữ liệu vào báo cáo, JasperSoft Studio cung cấp rất nhiều các công cụ làm việc với SQL như công cụ thiết kế truy vấn và tự động lấy thông tin và đăng ký các trường từ truy vấn trong report.

JasperSoft Studio không yêu cầu một truy vấn để sinh một báo cáo, nó có thể lấy dữ liệu từ một nguồn dữ liệu mà không cần định nghĩa bằng thực thi truy vấn. JasperReport hỗ trợ nhiều các ngôn ngữ truy vấn:
- CQL
- HiveQL
- JSON
- jsonQL
- MongoDBQuery
- PLSQL
- SQL
- XLS
- XPath
Nếu chọn nguồn dữ liệu là kết nối JDBC, JasperSoft Studio kiểm tra kết nối đến nguồn dữ liệu, nó cho phép JasperSoft Studio nhận diện các trường sử dụng thông tin metadata trong tập kết quả. Công cụ thiết kế sẽ liệt kê các trường công cụ tự động tìm ra, mỗi trường JasperSoft Studio xác định tên và dạng dữ liệu Java xác định bởi JDBC driver.
2. Tham số
2.1 Quản lý tham số
Tham số là các giá trị được truyền vào report từ ứng dụng, chúng có thể được sử dụng để thiết lập các đặc tính của báo cáo tại thời điểm xử lý báo cáo, ví dụ giá trị được sử dụng trong câu truy vấn SQL hoặc có thể cung cấp thêm các dữ liệu không được cung cấp bởi nguồn dữ liệu (ví dụ như tiêu đề báo cáo, đường dẫn đến ảnh trong báo cáo…). Nói cách khác, tham số chính là kênh giao tiếp chính giữa bộ máy xử lý báo cáo và môi trường thực thi (chính là ứng dụng). Tham số báo cáo có nhiều chức năng, chúng có thể được sử dụng trong câu điều kiện WHERE trong truy vấn SQL hoặc cung cấp thêm dữ liệu cho báo cáo. Một tham số được định nghĩa bằng một tên và một lớp, ví dụ tham số dạng java.sql.Connection có thể được sử dụng trong subreport, một ví dụ khác dạng đơn giản java.lang.Boolean có thể được sử dụng để hiển thị hoặc ẩn đi một phần báo cáo. Tham số có thể có giá trị mặc định được định nghĩa bởi thuộc tính expression. Biểu thức trong thuộc tính expression sẽ được JasperReport thực hiện khi giá trị cho tham số này không được cung cấp bởi người dùng lúc chạy. Các tham số của báo cáo đều có thể tìm thấy trong của sổ Outline ở nút Parameters.

Để tạo một tham số mới cho báo cáo, nhấp chuột phải vào nút Parameters và chọn Create Parameter, khi đó bên cửa sổ Properties sẽ có các thuộc tính cần thiết cho một tham số như tên, loại dữ liệu…

Các thuộc tính cơ bản của một tham số:
- Name: Tên tham số, viết liền.
- Class: Loại dữ liệu của tham số, mặc định là java.lang.String
- Description: Mô tả thuộc tính, giúp cho khi bạn di chuột vào tham số sẽ có một tooltip hiển thị tham số này mục đích làm gì.
- Is For Prompting: Cho phép JasperSoft Studio hiển thị tham số này trong cửa sổ nhập dữ liệu cho tham số khi báo cáo được thực thi hoặc tham số này có thể được truyền giá trị từ một ứng dụng ngoài.
- Default Value Expression: Thiết lập giá trị ban đầu cho tham số, giá trị này được sử dụng nếu không có giá trị nào được truyền cho tham số từ ứng dụng khi thực thi báo cáo. Chú ý, dạng dữ liệu giá trị truyền vào phải khớp với dạng dữ liệu khai báo trong thuộc tính Class của tham số.
2.2 Các tham số mặc định trong báo cáo
JasperReport cung cấp rất nhiều các tham số xây dựng sẵn bên trong bộ máy xử lý báo cáo. Các tham số này có thể in ra nhưng không thể thay đổi hoặc xóa chúng. Một vài các tham số xây dựng sẵn bạn thường dùng như: REPORT_CONNECTION: Với các báo cáo có nguồn dữ liệu sử dụng JDBC, tham số này lưu giữ kết nối JDBC được sử dụng để chạy câu truy vấn SQL. REPORT_DATA_SOURCE: Tham số này chứa nguồn dữ liệu được sử dụng để đưa vào báo cáo. REPORT_LOCALE: chứa tập hợp các thông tin địa phương như múi giờ, định dạng tiền tệ, ngày tháng, ngôn ngữ…
2.3 Sử dụng tham số trong truy vấn
2.3.1 Sử dụng tham số trong truy vấn SQL
Bạn có thể sử dụng các tham số trong truy vấn báo cáo nếu ngôn ngữ đó hỗ trợ, JasperReport thực hiện các truy vấn, truyền giá trị vào các tham số được sử dụng trong câu truy vấn. Có hai cách sử dụng các tham số trong câu truy vấn, cách thứ nhất là tham số của báo cáo hoạt động giống tham số SQL chuẩn, cách thứ hai là tham số của báo cáo được ghép chuỗi với truy vấn trước khi thực thi.
Cách 1: Với các câu truy vấn SQL, chúng ta có thể sử dụng các tham số trong mệnh đề where để lọc các bản ghi kết quả. Tham số có thể hoạt động giống như tham số SQL tiêu chuẩn, ví dụ:
Code language: PHP (php)SELECT * FROM ORDERS WHERE ID = $P{order_id}
Trong ví dụ này, tham số order_id chứa ID của đơn hàng cần lấy dữ liệu đưa vào vào báo. Tham số này có thể truyền vào báo cáo từ ứng dụng. Chú ý, tham số ở đây là một tham số SQL tiêu chuẩn, điều đó có nghĩa là truy vấn này có thể được thực thi giống như câu truy vấn:
SELECT * FROM ORDERS WHERE ID = ?
và giá trị của tham số order_id được truyền vào câu truy vấn trên.
Cách 2: Trong truy vấn:
Code language: PHP (php)SELECT * FROM ORDERS ORDER BY $P!{order_field}
khi đó tham số order_field không được xử lý như tham số SQL, JasperReport đọc thấy cú pháp đặc biệt 𝑃!𝑣à𝑡ℎ𝑎𝑦𝑡ℎế𝑛ó𝑏ở𝑖𝑔𝑖á𝑡𝑟ị𝑐ủ𝑎𝑡ℎ𝑎𝑚𝑠ố.𝑉ớ𝑖𝑐á𝑐ℎ𝑡ℎứ𝑐𝑛à𝑦𝑏ạ𝑛𝑐ó𝑡ℎể𝑡𝑟𝑢𝑦ề𝑛𝑣à𝑜𝑚ộ𝑡𝑡𝑟𝑢𝑦𝑣ấ𝑛độ𝑛𝑔𝑣ớ𝑖𝑐ú𝑝ℎá𝑝:P!vàthaythếnóbởigiátrịcủathamsố.Vớicáchthứcnàybạncóthểtruyềnvàomộttruyvấnđộngvớicúpháp:P!{my_query}
Một truy vấn có thể truyền vào nhiều các tham số khác nhau, khi sử dụng tham số, cần thiết lập một giá trị mặc định cho tham số để JasperSoft Studio thực thi các truy vấn.
2.3.2 Sử dụng tham số với các giá trị NULL
Khi tham số có giá trị NULL, nếu sử dụng tham số như là tham số SQL tiêu chuẩn, câu truy vấn hoạt động sẽ không đúng, khi đó chúng ta cần đến một cú pháp là
Code language: PHP (php)$X{EQUAL, fieldname, parmetername}
Xem ví dụ tiếp theo để hiểu hơn về cú pháp này: Câu truy vấn 1:
Code language: PHP (php)SELECT * FROM PRODUCTS WHERE EXPIRE_DATE = $P{pr_expire_date}
Câu truy vấn 2:
Code language: PHP (php)SELECT * FROM PRODUCTS WHERE $X{EQUAL, EXPIRE_DATE, pr_expire_date}
Nếu tham số pr_expire_date khác NULL, cả hai câu truy vấn trên có kết quả giống nhau, nhưng nếu tham số này có giá trị NULL, kết quả sẽ có sự khác biệt. Câu truy vấn 1 sẽ tương đương:
SELECT * FROM PRODUCTS WHERE EXPIRE_DATE = NULL
Code language: PHP (php)
Câu truy vấn 2 sẽ khác với câu truy vấn 1:
SELECT * FROM PRODUCTS WHERE EXPIRE_DATE IS NULL
Code language: PHP (php)
2.3.3 Mệnh đề IN, NOTIN trong truy vấn SQL
JaperReport cung cấp một cú pháp đặc biệt để làm việc với mệnh đề IN và NOTIN trong câu truy vấn SQL. Ví dụ câu truy vấn
SELECT * FROM PRODUCTS WHERE MADE_IN IS IN ('Vietnam', 'USA', 'French')
Code language: JavaScript (javascript)
Khi đó chúng ta sử dụng cú pháp $X{} để thực hiện đưa tham số vào mệnh đề IN như sau:
Code language: PHP (php)SELECT * FROM PRODUCTS WHERE $X{IN, MADE_IN, made_in_list}
Trong đó made_in_list là một danh sách dạng java.util.Collection hoặc một mảng.
2.3.4 Xử lý ngày tháng trong câu truy vấn
Trong báo cáo có thể truy vấn lọc kết quả dựa trên các thông tin ngày tháng từ ngày giờ hiện tại của hệ thống bằng cách sử dụng tham số dạng DateRange. Tham số dạng DateRange có thể là ngày hoặc một biểu thức dạng text…
Biểu thức dạng text có thể sử dụng định dạng
<từ_khóa> +/- <n>
Code language: HTML, XML (xml)
trong đó:
- từ_khóa: xác định dạng thời gian muốn sử dụng: DAY, WEEK, MONTH, QUARTER, SEMI và YEAR.
- +/- sử dụng khi bạn muốn một thời gian trước (-) hoặc sau (+) một ngày nào đó.
- n: xác định số quãng thời gian.
Ví dụ, bạn muốn xem các đơn hàng trong tháng trước thì biểu thức của tham số sẽ là MONTH – 1 Để tạo một tham số dạng DateRange thì thuộc tính class của tham số phải là các giá trị sau: net.sf.jasperreports.types.date.DateRange: Chỉ chứa dữ liệu dạng ngày tháng năm YYYY-MM-DD net.sf.jasperreports.types.date.TimestampRange: Dữ liệu dạng cả ngày tháng và thời gian YYYY-MM-DD HH:mm:ss. Ví dụ:
<parameter name="closedTime" class="net.sf.jasperreports.types.date.TimestampRange">
Code language: JavaScript (javascript)
Để sử dụng tham số DateRange trong truy vấn chúng ta phải sử dụng cú pháp 𝑋𝑣ìXvìP{ } không hỗ trợ dạng date-range. Ví dụ:
new net.sf.jasperreports.types.date.DateRangeBuilder("DAY-1").toDateRange()
Code language: CSS (css)
chuyển dạng text có từ khóa thành DateRange
new net.sf.jasperreports.types.date.DateRangeBuilder("WEEK").set(Timestamp.class).toDateRange()
Code language: CSS (css)
chuyển chuỗi có từ khóa thành dạng TimestampRange
new net.sf.jasperreports.types.date.DateRangeBuilder("2019-02-11").toDateRange()
Code language: CSS (css)
chuyển ngày định dạng YYYY-MM-DD thành dạng DateRange
new net.sf.jasperreports.types.date.DateRangeBuilder("2019-02-11 15:47:00").toDateRange()
Code language: CSS (css)
chuyển ngày định dạng YYYY-MM-DD HH:mm:ss thành dạng TimestampRange Ví dụ về việc sử dụng tham số trong JRXML:
<parameter name="myParameter" class="net.sf.jasperreports.types.date.DateRange"><defaultvalueexpression></defaultvalueexpression></parameter>
Code language: HTML, XML (xml)
Một ví dụ khác:
<parameter class="net.sf.jasperreports.types.date.DateRange" name="EndDate"><defaultvalueexpression></defaultvalueexpression></parameter>
Code language: HTML, XML (xml)
Khi bạn tạo ra một điều khiển nhập liệu cho tham số DateRange hoặc TimestampRange có thể nhập trực tiếp hoặc sử dụng calendar widget. Sử dụng BETWEEN để thiết lập điều khiển nhập liệu cho phép người dùng xác định một khoảng thời gian chứ không phải một mốc thời gian. Để làm điều này: + Định nghĩa hai tham số DateRange, ví dụ StartDate và EndDate. + Thiết lập giá trị mặc định cho một hoặc cả hai tham số sử dụng defaultValueExpression. + Sử dụng biểu thức 𝑋𝐵𝐸𝑇𝑊𝐸𝐸𝑁,…𝑡𝑟𝑜𝑛𝑔𝑐â𝑢𝑡𝑟𝑢𝑦𝑣ấ𝑛+𝑇ạ𝑜𝑚ộ𝑡đ𝑖ề𝑢𝑘ℎ𝑖ể𝑛𝑛ℎậ𝑝𝑙𝑖ệ𝑢𝑑ạ𝑛𝑔𝑑𝑎𝑡𝑒𝑐ℎ𝑜𝑚ỗ𝑖𝑡ℎ𝑎𝑚𝑠ố𝑆𝑡𝑎𝑟𝑡𝐷𝑎𝑡𝑒𝑣à𝐸𝑛𝑑𝐷𝑎𝑡𝑒.𝑉í𝑑ụ𝐽𝑅𝑋𝑀𝐿𝑑ướ𝑖đâ𝑦𝑠ử𝑑ụ𝑛𝑔𝑡ừ𝑘ℎó𝑎𝐵𝐸𝑇𝑊𝐸𝐸𝑁𝑡𝑟𝑜𝑛𝑔𝑏𝑖ể𝑢𝑡ℎứ𝑐XBETWEEN,…trongcâutruyvấn+TạomộtđiềukhiểnnhậpliệudạngdatechomỗithamsốStartDatevàEndDate.VídụJRXMLdướiđâysửdụngtừkhóaBETWEENtrongbiểuthứcX{ } để tìm tất cả các dữ liệu trong 20 năm trước đó:
<parameter name="StartDate" class="net.sf.jasperreports.types.date.DateRange"><defaultvalueexpression></defaultvalueexpression></parameter>
<parameter name="EndDate" class="net.sf.jasperreports.types.date.DateRange"><defaultvalueexpression></defaultvalueexpression></parameter>
Code language: HTML, XML (xml)
3. Biến số trong JasperReport
3.1 Các biến số người dùng tạo ra
Bạn có thể sử dụng biến số để lưu trữ các kết quả riêng hoặc thực hiện các tính toán phức tạp với dữ liệu được trích xuất từ nguồn dữ liệu.

Để tạo một biến số, trong cửa sổ Outline nhấp chuột phải vào nút Variables chọn Create Variable, một biến số mới sẽ được thêm vào danh sách biến số.

Biến số cũng có các thuộc tính cơ bản:
- Name: Tên biến số, được sử dụng để tham chiếu đến biến số sau này trong các biểu thức với cú pháp $V{ten_bien_so}.
- Value Class Name: Dạng dữ liệu của biến số.
- Calculation: Khi sử dụng hàm tính toán, giá trị của biến số không được xác định bởi biểu thức của nó, thay vào đó, nó truyền giá trị vào hàm tính toán. Có rất nhiều các hàm tính toán được xây dựng sẵn trong JasperSoft Studio: Sum, Count, Lowest, Highest…
- Expression: Biểu thức xác định giá trị của biến số, nó có thể được tổ hợp từ nhiều trường và nhiều biến số khác thông qua các toán tử logic, toán tử toán học… JasperSoft Studio cung cấp một trình soạn thảo biểu thức giúp cho việc viết mã các biểu thức trở lên đơn giản. Nếu không có hàm tính toán nào được thiết lập trong thuộc tính Calculation, kết quả của biểu thức được gán cho biến số.
- Initial Value Expression: Thiết lập giá trị của biến số tại thời điểm ban đầu trước khi tính toán đầu tiền thực hiện với biểu thức trong thuộc tính expression. Ví dụ: chúng ta có một biến số tên Variable1 và biểu thức của nó là new Integer(5) Tại mỗi lần lặp lại khi báo cáo đi qua các bản ghi kết quả, biến số được gán giá trị là số nguyên 5. Khi đó giá trị khởi tạo là không cần thiết, nhưng nếu biểu thức của một biến khác Variable2 là: $V(Variable1) + 5 tại mỗi lần lặp lại qua các bản ghi kết quả của truy vấn, giá trị được tăng thêm 5. Trong trường hợp này giá trị khởi tạo là cần thiết vì giá trị của Variable1 là undefined tại lần lặp đầu tiên, tất cả các thực hiện tính toán sau đó sẽ lỗi.
- Increment Type: Khi hàm tính toán được thiết lập trong thuộc tính Calculation, giá trị của biểu thức được truyền vào hàm tính toán để tính giá trị cho biến số. Mặc định việc gọi hàm tính toán được thực hiện cho mỗi lần đọc bản ghi từ tập kết quả truy vấn, nhưng có thể cần những thời điểm gọi hàm tính toán khác đi.
- Report: Hàm tính toán được gọi chỉ ở cuối report, sau đó truyền giá trị tính toán được của biểu thức vào biến số tại thời điểm này.
- Page: Hàm tính toán được gọi cuối mỗi trang
- Column: Hàm tính toán được gọi cuối mỗi cột.
- Incrementer Factory Class Name: hàm tính toán rất hữu ích nhưng bị giới hạn chỉ sử dụng cho kiểu số. Có trường bạn muốn thực hiện trên dạng dữ liệu khác, giả sử như kiểu String chẳng hạn, bạn muốn nối các chuỗi sau mỗi lần lặp, để làm được điều này cần định nghĩa một Incrementer (một đoạn code java được mở rộng từ interface JRIncrementerFactory).
- Reset Type: định nghĩa khi một biến số cần khởi tạo lại giá trị ban đầu ở những thời điểm nhất định. Thuộc tính này hữu ích khi thực hiện các tính toán như tổng, giá trị trung tình … từ vài các bản ghi trong kết quả truy vấn.
- Report: Biến số được khởi tạo chỉ lần đầu tiên khi báo cáo được tạo ra.
- Page: Biến số được khởi tạo lại ở mỗi trang
- Column: Biến số được khởi tạo lại trong mỗi cột mới
3.2 Các biến số được xây dựng sẵn trong JasperReport
JasperSoft Studio xây dựng sẵn một số các biến số giúp bạn đưa thông tin vào báo cáo nhanh chóng hơn:
- PAGE_NUMBER: Chứa số trang của trang hiện tại
- COLUMN_NUMBER: Chứa số cột hiện tại
- REPORT_COUNT: Chứa số bản ghi được xử lý
- PAGE_COUNT
- COLUMN_COUNT
Cảm ơn các bạn đã đọc.
Các bạn có thể tham khảo các bài viết hay về Laravel tại đây.
Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.
Nguồn tham khảo: Allaravel
Leave a Reply