Mang đến cho bạn hành trang là Kiến thức và Kinh nghiệm

Lựa chọn chủ đề bạn quan tâm

Cùng nhau thảo luận về các vấn đề

Hãy theo dõi chúng tôi nếu bạn thấy bổ ích

  1. Hỏi đáp IT
  2. Hỏi nhanh

Sử dụng Bean Datasource và Subreport để tạo nhiều danh sách trong báo cáo với JasperReports

2003 Lượt xem 1 Bình luận 0 Lượt báo xấu
Bài viết “Sử dụng Bean Datasource trong Jasper Report” đã chỉ ra cách để tạo ra một báo cáo với JasperReports sử dụng Bean Datasource. Bài viết đó cũng có một ví dụ minh họa mà ở đó hiển thị một danh sách sinh viên từ bean datasource lên báo cáo. Vấn đề đặt ra là nếu giờ ta có thêm một danh sách các lớp học và muốn hiển thị danh sách này sau danh sách sinh viên trên thì ta phải làm thế nào ? Một trong những giải pháp là sử dụng Subreport. Subreport là một thành phần mà JasperReports cung cấp và rất hữu ích trong các trường hợp báo cáo của chúng ta có nhiều danh sách dữ liệu, đặc biệt là khi các danh sách dữ liệu này được lấy ra từ các nguồn khác nhau (ví dụ như có danh sách phải lấy ra từ database, có danh sách lấy từ bean datasource chẳng hạn). Bài viết này sẽ có một ví dụ về việc hiển thị hai danh sách dữ liệu được lấy ra từ hai bean datasource khác nhau bằng việc sử dụng Subreport. Qua đó hi vọng có thể giới thiệu với bạn đọc một chút kiến thức về thành phần này.
Trong bài viết này, các file báo cáo vẫn được tạo ra bằng công cụ iReport Designer như ở các bài viết trước. Tuy nhiên chỉ các bước quan trọng mới được đề cập đến, nếu bạn đọc muốn biết chi tiết các bước trong việc tạo một báo cáo với iReport, bạn đọc có thể tham khảo bài viết “Tạo báo cáo với JasperReports” trước khi đọc bài viết này.
Dùng iReport tạo một file báo cáo có tên là SubReportStudent.jrxml như hình dưới đây:

Trong file SubReportStudent.jrxml trên, ta tạo 3 field có tên lần lượt là id, name, và mark. Các field này được kéo vào phần Detail 1 của báo cáo. Phần Column Header sẽ là các label tương ứng với 3 field trên. Các phần khác của báo cáo (Title, Page Header,…) sẽ được xóa đi. File báo cáo này được tạo ra để hiển thị danh sách sinh viên.
Làm tương tự như trên, tao ra file báo cáo có tên là SubReportClass.jrxml với các field là id và nameđể hiển thị danh sách các lớp học như hình dưới đây:

Tiếp theo tạo một file báo cáo có tên là StudentClassReport.jrxml. Đây là file báo cáo chính, nội dung hai file báo cáo mà chúng ta tạo ở trên sẽ được nhúng vào nội dung file báo này qua việc sử dụng thành phần Subreport như hình dưới đây:

Thành phần Subreport nằm trong mục Report Elements ở cửa sổ Palette. Để mở của sổ này lên thì trong iReport ta có thể chọn menu Window, sau đó trong menu này chọn mục Palette (hoặc dùng tổ hợp phím Ctr+Shif+8).
Kéo thành phần này vào nội dung của file báo cáo StudentClassReport.jrxml, một cửa sổ popup sẽ hiện lên như hình dưới đây:

Trong cửa sổ popup trên, ta chọn Just create the subreport element rồi chọn Finish, như vậy ta có một thành phần Subreport nằm trong phần nội dung Detail 1 của file StudentClassReport.jrxml. Thành phần này sẽ tham chiếu tới SubReportStudent.jrxml để hiển thị lên một danh sách sinh viên
Trong cửa sổ Report Inspector ta click chuột phải vào phần Detail 1 của fileStudentClassReport.jrxml và chọn Add Another Detail Band, phần Detail 2 sẽ được tạo ra trong báo cáo. Sau đó ta lại kéo tiếp một thành phần Subreport vào phần Detail 2 cho việc hiển thị danh sách các lớp học. Các bước tương tự như các bước đã nói ở trên.
Cuối cùng file StudentClassReport.jrxml sẽ giống như dưới đây

Click vào thành phần Subreport nằm trong phần Detail 1, trong của sổ Properties hiện ra tương ứng bên phải, ta đặt giá chị cho một số thuộc tính như sau:

  • Subreport Expression : có giá trị của tham số $P{StudentSubReport}
  • Expression Class : Nhập net.sf.jasperreports.engine.JasperReport
  • Connection type : Chọn Use a datasource expression
  • Data Source Expression : có giá trị của tham số $P{StudentDataSource}

Kết quả sẽ giống như hình dưới đây

Làm tương tự cho thành phần Subreport trong phần Detail 2, chỉ khác ở hai tham số là$P{ClassSubReport} và $P{ClassDataSource} như hình dưới đây:

Quay trở lại cửa sổ Report Inspector, tạo 4 tham số là StudentSubReport, StudentDataSource,ClassSubReport và ClassDataSource như hình dưới đây

Click vào từng tham số trên và chỉnh thuộc tính Parameter Class trong cửa sổ Properties lần lượt như hình dưới đây:




Dùng Eclipse IDE tạo một project giống như hình dưới đây, copy 3 file báo cáo được tạo ở trên vào trong source folder có tên là reports.

Trong ví dụ này, ta sử dụng lại hai lớp Student.java và StudentDAO.java trong ví dụ của bài viết “Sử dụng Bean Datasource trong Jasper Report“. Ngoài ra ta viết thêm hai lớp là Clazz.java vàClazzDAO.java để biểu diễn một đối tượng lớp học và trả về một danh sách các đối tượng kiểu lớp học.
Clazz.java


Code:
package jasperreport.subreport.beandatasource; public class Clazz { private String id; private String name; public Clazz(String id, String name){ this.id = id; this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
ClazzDAO.java


Code:
package jasperreport.subreport.beandatasource; import java.util.Arrays; import java.util.List; public class StudentDAO { public static List getStudentList(){ Student [] students = new Student []{ new Student(1, "Nguyen Van A", 5), new Student(2, "Nguyen Van B", 8), new Student(3, "Nguyen Van C", 5.5), new Student(4, "Nguyen Van D", 7), new Student(5, "Nguyen Van E", 9), new Student(6, "Nguyen Van F", 5), new Student(7, "Nguyen Van G", 5), new Student(8, "Nguyen Van H", 10), new Student(9, "Nguyen Van I", 5), new Student(10, "Nguyen Van J", 4.6) }; return Arrays.asList(students); } }
Điểm bắt đầu của chương trình nằm trong file DemoMain.java
DemoMain.java


Code:
 package jasperreport.subreport.beandatasource;    import java.io.File;   import java.io.FileOutputStream;   import java.io.OutputStream;   import java.util.HashMap;   import java.util.Map;   import net.sf.jasperreports.engine.JREmptyDataSource;   import net.sf.jasperreports.engine.JasperCompileManager;   import net.sf.jasperreports.engine.JasperExportManager;   import net.sf.jasperreports.engine.JasperFillManager;   import net.sf.jasperreports.engine.JasperPrint;   import net.sf.jasperreports.engine.JasperReport;   import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;   import net.sf.jasperreports.engine.util.JRLoader;    public class DemoMain {        public static void main(String [] args){             Map parameters = new HashMap();             try {                   JasperReport jrSubStudent = loadJasperReport("reports/SubReportStudent");                  parameters.put("StudentSubReport", jrSubStudent);                  parameters.put("StudentDataSource", new JRBeanCollectionDataSource(StudentDAO.getStudentList()));                  JasperReport jrSubClass = loadJasperReport("reports/SubReportClass");                  parameters.put("ClassSubReport", jrSubClass);                  parameters.put("ClassDataSource", new JRBeanCollectionDataSource(ClazzDAO.getClassList()));                  JasperReport jr = loadJasperReport("reports/StudentClassReport");                  JasperPrint jp = JasperFillManager.fillReport(jr, parameters, new JREmptyDataSource());                  OutputStream os = new FileOutputStream("D:/StudentReport.pdf");                   JasperExportManager.exportReportToPdfStream(jp, os);                   os.flush();                   os.close();              } catch (Exception e) {                  e.printStackTrace();              }         }        private static JasperReport loadJasperReport(String reportName){             try{                  File f = new File(reportName+".jasper");                  if(!f.exists()){                       JasperCompileManager.compileReportToFile(reportName+".jrxml", reportName+".jasper");                       f = new File(reportName+".jasper");                  }                  JasperReport jr = (JasperReport) JRLoader.loadObject(f);                  return jr;             }catch(Exception e){                  e.printStackTrace();             }             return null;        }     }  

Hàm loadJasperReport() sẽ nhận vào là tên của file báo cáo sau đó sẽ trả về một đối tượngJasperReport tương ứng với file báo cáo có tên được truyền vào. Trong hàm main(), các tham số lần lượt được gán các giá trị tương ứng và được truyền vào file báo cáo chính qua một Map có tên làparameters. File báo cáo chính (StudentClassReport) sẽ nhận tham số truyền vào và điền dữ liệu vào các thành phần bên trong nó. Cuối cùng một file .Pdf sẽ được tạo ra hiển thị danh sách sinh viên và danh sách lớp học như hình dưới đây:

Như vậy qua bài viết với ví dụ minh họa, ta thấy được với việc sử dụng Subreport, ta có thể tạo ra một file báo cáo hiển thị nhiều danh sách lấy từ các nguồn dữ liệu khác nhau. Một lần nữa xin nhắc lại, Subreport thật sự là một thành phần quan trọng và hữu ích mà JasperReports cung cấp cho chúng ta để phục vụ cho việc tạo ra các báo cáo phức tạp. Bài viết hi vọng đã cung cấp cho bạn đọc một số kiến thức trong việc sử dụng thành phần này.
Good luck!
Câu trả lời

- Bạn đã sẵn sàng thảo luận về chủ đề này. Hãy bấm "Viết bình luận", bạn có thể lựa chọn sử dụng tài khoản Facebook hoặc Google++

- Vì sự phát triển của cộng đồng CNTT/CNPM tại Việt Nam!

Unknown user
No responses yet

Cảm ơn anh đã chia sẻ
0 Lượt thích

Từ khóa tìm kiếm

Câu trả lời mới nhất

Tin tuyển dụng