דיווח BIRT עם מגף האביב

1. הקדמה

במדריך זה אנו נשלב את BIRT (כלי בינה ודיווח עסקי) עם Spring Boot MVC, כדי להגיש דוחות סטטיים ודינמיים בפורמט HTML ו- PDF.

2. מה זה BIRT?

BIRT הוא מנוע קוד פתוח ליצירת הדמיות נתונים שניתן לשלב ביישומי אינטרנט של Java.

מדובר בפרויקט תוכנה ברמה העליונה בקרן Eclipse וממנף תרומות של IBM ו- Innovent Solutions. זה הוקם ובחסות Actuate בסוף 2004.

המסגרת מאפשרת יצירת דוחות המשולבים במגוון רחב של מקורות נתונים.

3. תלות Maven

ל- BIRT שני מרכיבים עיקריים: מעצב דוחות חזותיים ליצירת קבצי עיצוב דוחות ורכיב זמן ריצה לפירוש ועיבוד אותם עיצובים.

ביישום האינטרנט לדוגמה שלנו, אנו נשתמש בשניהם על גבי אתחול האביב.

3.1. תלות מסגרת BIRT

כפי שאנו רגילים לחשוב במונחים של ניהול תלות, הבחירה הראשונה תהיה לחפש BIRT במוואן סנטרל.

למרות זאת, הגרסה הרשמית האחרונה של ספריית הליבה שזמינה היא 4.6 החל משנת 2016, בעוד בדף ההורדה של ליקוי חמה, אנו יכולים למצוא קישורים לשתי גרסאות חדשות יותר לפחות (הזרם הוא 4.8).

אם אנו בוחרים ללכת על הבנייה הרשמית, הדרך הקלה ביותר להפעיל את הקוד היא להוריד את חבילת BIRT Report Engine, שהיא יישום אינטרנט שלם שימושי גם ללמידה. לאחר מכן עלינו להעתיק אותה lib התיקייה לפרויקט שלנו (כ- 68 מגה-בייט בגודל) ותאמר ל- IDE לכלול את כל הצנצנות בו.

מובן מאליו שבאמצעות גישה זו, נוכל לקמפל רק באמצעות ה- IDE, שכן Maven לא ימצא את הצנצנות האלה אלא אם כן אנו מגדירים ומתקינים אותן באופן ידני (יותר מ -100 קבצים!) ברפיון המקומי שלנו.

לְמַרְבֶּה הַמַזָל, פתרונות חדשניים החליטה לקחת את העניינים בידיה ופרסמה ב- Maven Central את המבנים שלה של התלות האחרונה ב- BIRT, וזה נהדר, שכן היא מנהלת עבורנו את כל התלות הדרושה.

כשקוראים הערות בפורומים מקוונים, לא ברור אם חפצים אלה מוכנים לייצור, אך Innovent Solutions עבדה על הפרויקט לצד צוות הליקוי מאז תחילתו, ולכן הפרויקט שלנו מסתמך עליהם.

קל מאוד להכניס BIRT:

 com.innoventsolutions.birt.runtime org.eclipse.birt.runtime_4.8.0-20180626 4.8.0 

3.2. תלות במגף האביב

כעת, כאשר BIRT מיובא לפרויקט שלנו, עלינו רק להוסיף את התלות הרגילה של Spring Boot בקובץ ה- pom שלנו.

אולם יש מלכודת אחת מכיוון שצנצנת BIRT מכילה יישום משלה של Slf4J, שלא משחק איתו יפה לוגבק וזורק חריג קונפליקט במהלך ההפעלה.

מכיוון שאיננו יכולים להסיר אותו מהצנצנת, כדי לפתור בעיה זו, עלינו לא לכלול לוגבק:

 org.springframework.boot spring-boot-starter-logging ch.qos.logback logback-classic 

עכשיו סוף סוף אנחנו מוכנים להתחיל!

4. דוחות BIRT

במסגרת BIRT, דוח הוא קובץ תצורה XML ארוך, שזוהה על ידי התוסף rptdesign.

זה אומר למנוע מה לצייר ולאן, החל מסגנון הכותרת ועד למאפיינים הנדרשים להתחברות למקור נתונים.

לדוח דינמי בסיסי עלינו להגדיר שלושה דברים:

  1. מקור הנתונים (בדוגמה שלנו אנו משתמשים בקובץ CSV מקומי, אך הוא יכול בקלות להיות טבלת מסד נתונים)
  2. האלמנטים שאנחנו רוצים להציג (תרשימים, טבלאות וכו ')
  3. עיצוב הדף

הדוח בנוי כמו דף HTML, עם כותרת עליונה, גוף, כותרת תחתונה, סקריפטים וסגנונות.

המסגרת מספקת מערך רכיבים נרחב לבחירה מחוץ לקופסה, כולל אינטגרציה למקורות נתונים, פריסות, תרשימים וטבלאות מיינסטרים. ונוכל להאריך אותו כדי להוסיף משלנו!

ישנן שתי דרכים ליצור קובץ דוח: ויזואלי או פרוגרמטי.

5. מעצב דוחות הליקוי

כדי להקל על יצירת דוחות, צוות הליקוי בנה כלי לעיצוב דוחות תוסף עבור ה- IDE הפופולרי שלו.

כלי זה כולל ממשק גרור ושחרר קל מ ה לוּחַ הַצְבָעִים משמאל, הפותח אוטומטית את חלון ההתקנה של הרכיב החדש שאנו מוסיפים לדף. אנו יכולים גם לראות את כל ההתאמות האישיות הזמינות עבור כל רכיב על ידי לחיצה עליו בדף ואז על עורך נכסים כפתור (מודגש בתמונה למטה).

כדי לדמיין את מבנה העמוד כולו בתצוגת עץ, עלינו רק ללחוץ על ה- מתווה לַחְצָן.

ה סייר נתונים הכרטיסייה מכילה גם את מקורות הנתונים שהוגדרו לדוח שלנו:

את דוח הדוגמה המוצג בתמונה ניתן למצוא בנתיב /reports/csv_data_report.rptdesign

יתרון נוסף של ללכת על המעצב הויזואלי הוא התיעוד המקוון, שמתמקד יותר בכלי זה במקום בגישה הפרוגרמטית.

אם אנו כבר משתמשים ב- Eclipse, עלינו להתקין את הפלאגין BIRT Report Design, הכוללת פרספקטיבה מוגדרת מראש ואת העורך הויזואלי.

עבור אותם מפתחים שאינם משתמשים כעת ב- Eclipse ולא רוצים לעבור, יש חבילת מעצב דוחות ליקוי חמה, המורכב ממתקן ליקוי חמה נייד עם תוסף BIRT המותקן מראש.

לאחר סיום קובץ הדוח, אנו יכולים לשמור אותו בפרויקט שלנו ולחזור לקידוד בסביבה המועדפת עלינו.

6. הגישה הפרוגרמטית

אנחנו יכולים גם לעצב דוח באמצעות קוד בלבד, אך גישה זו קשה הרבה יותר בגלל התיעוד הלקוי שיש, לכן היה מוכן לחפור בקוד המקור ובפורומים מקוונים.

כדאי גם לשקול כי כל ה פרטי עיצוב מייגעים כמו גודל, אורך ומיקום רשת הרבה יותר קל להתמודד עם השימוש במעצב.

להוכחת נקודה זו, הנה דוגמה כיצד להגדיר דף סטטי פשוט עם תמונה וטקסט:

אלמנט DesignElementHandle = factory.newSimpleMasterPage ("עמוד מאסטר"); design.getMasterPages (). להוסיף (אלמנט); רשת GridHandle = factory.newGridItem (null, 2, 1); design.getBody (). להוסיף (רשת); grid.setWidth ("100%"); RowHandle row0 = (RowHandle) grid.getRows (). Get (0); ImageHandle image = factory.newImage (null); CellHandle cell = (CellHandle) row0.getCells (). Get (0); cell.getContent (). הוסף (תמונה); image.setURL ("\" // www.baeldung.com/wp-content/themes/baeldung/favicon/favicon-96x96.png \ ""); LabelHandle label = factory.newLabel (null); cell = (CellHandle) row0.getCells (). get (1); cell.getContent (). הוסף (תווית); label.setText ("שלום עולם הבאלדונג!");

קוד זה ייצור דוח פשוט (ומכוער):

דוח הדוגמה המוצג בתמונה לעיל נמצא בנתיב זה: /reports/static_report.rptdesign.

לאחר שקידדנו כיצד הדוח אמור להיראות ואילו נתונים עליו להציג, נוכל ליצור את קובץ ה- XML ​​על ידי הפעלת שלנו ReportDesignApplication מעמד.

7. צירוף מקור נתונים

הזכרנו קודם כי BIRT תומך במקורות נתונים רבים ושונים.

עבור פרויקט הדוגמה שלנו, השתמשנו בקובץ CSV פשוט עם שלושה ערכים. ניתן למצוא אותו ב דיווחים תיקייה ומורכב משלוש שורות פשוטות של נתונים, בתוספת כותרות:

סטודנט, מתמטיקה, גיאוגרפיה, הצעת חוק, 10,3,8 טום, 5,6,5 אן, 7, 4,9

7.1. קביעת תצורה של מקור הנתונים

כדי לאפשר ל- BIRT להשתמש בקובץ שלנו (או בכל סוג אחר של מקור), עלינו להגדיר א מקור מידע.

עבור הקובץ שלנו, יצרנו א מקור נתונים שטוח לקבצים עם מעצב הדוחות, הכל בכמה צעדים ספורים:

  1. פתח את נקודת המבט של המעצב והסתכל על מתווה בצד ימין.
  2. לחץ לחיצה ימנית על מקורות מידע סמל.
  3. בחר את סוג המקור הרצוי (במקרה שלנו מקור הקובץ השטוח).
  4. כעת אנו יכולים לבחור לטעון תיקיה שלמה או רק קובץ אחד. השתמשנו באפשרות השנייה (אם קובץ הנתונים שלנו הוא בפורמט CSV, אנחנו רוצים לוודא להשתמש בשורה הראשונה כמחוון שם העמודה).
  5. בדוק את החיבור כדי לוודא שהנתיב תקין.

צירפנו כמה תמונות כדי להראות כל שלב:

7.2. מערך הנתונים

מקור הנתונים מוכן, אך עדיין עלינו להגדיר את שלנו מערך נתונים, שהם הנתונים בפועל המוצגים בדוח שלנו:

  1. פתח את נקודת המבט של המעצב והסתכל על מתווה בצד ימין.
  2. לחץ לחיצה ימנית על מערכי נתונים סמל.
  3. בחר את הרצוי מקור מידע והסוג (במקרה שלנו יש רק סוג אחד).
  4. המסך הבא תלוי בסוג מקור הנתונים ומערכת הנתונים שבחרנו: במקרה שלנו אנו רואים דף בו אנו יכולים לבחור את העמודות שייכללו.
  5. לאחר השלמת ההתקנה, אנו יכולים לפתוח את התצורה בכל עת על ידי לחיצה כפולה על מערך הנתונים שלנו.
  6. ב עמודות פלט, אנו יכולים להגדיר את הסוג הנכון של הנתונים המוצגים.
  7. לאחר מכן נוכל להסתכל בתצוגה מקדימה על ידי לחיצה על תצוגה מקדימה של תוצאות.

שוב, כמה תמונות להבהרת השלבים הבאים:

7.3. סוגי מקורות נתונים אחרים

כאמור בשלב 4 של מערך נתונים בתצורה, האפשרויות הזמינות עשויות להשתנות בהתאם מקור מידע מיוחס.

עבור קובץ ה- CSV שלנו, BIRT נותן אפשרויות הקשורות לאילו עמודות להציג, לסוג הנתונים ואם ברצוננו לטעון את כל הקובץ. מצד שני, אם היה לנו מקור נתונים JDBC, ייתכן שנצטרך לכתוב שאילתת SQL או נוהל מאוחסן.

מ ה מערכי נתונים תַפרִיט, אנו יכולים גם להצטרף לשתי קבוצות נתונים או יותר במערך נתונים חדש.

8. העברת הדוח

לאחר שקובץ הדו"ח מוכן, עלינו להעביר אותו למנוע להצגה. לשם כך, יש כמה דברים ליישם.

8.1. אתחול המנוע

ה ReportEngine class, שמפרש את קבצי העיצוב ויוצר את התוצאה הסופית, הוא חלק מספריית זמן הריצה של BIRT.

הוא משתמש בחבורה של עוזרים ומשימות כדי לבצע את העבודה, מה שהופך אותה למדי למשאבים:

מקור תמונה: תיעוד BIRT ליקוי חמה

יש עלות משמעותית הקשורה ליצירת מופע מנוע, בעיקר בשל עלות טעינת הרחבות. לָכֵן, עלינו ליצור רק אחד ReportEngine למשל ולהשתמש בו להפעלת מספר דוחות.

מנוע הדו"ח נוצר באמצעות מפעל המסופק על ידי פּלַטפוֹרמָה. לפני יצירת המנוע, עלינו להתניע את פּלַטפוֹרמָה, אשר יטען את התוספים המתאימים:

@PostConstruct מוגן חלל לאתחל () זורק BirtException {EngineConfig config = EngineConfig חדש (); config.getAppContext (). put ("קפיץ", this.context); Platform.startup (config); מפעל IReportEngineFactory = (IReportEngineFactory) פלטפורמה .createFactoryObject (IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY); birtEngine = factory.createReportEngine (config); imageFolder = System.getProperty ("user.dir") + File.separatorChar + reportsPath + imagesPath; loadReports (); }

כשאנחנו לא צריכים את זה יותר, אנחנו יכולים להרוס את זה:

@ ביטול חלל ציבורי הרס () {birtEngine.destroy (); Platform.shutdown (); }

8.2. יישום פורמט הפלט

BIRT כבר תומך במספר פורמטי פלט:HTML, PDF, PPT ו- ODT, עד כמה שם.

עבור פרויקט המדגם, יישמנו שניים מהם בשיטות createPDFReport ו ליצור HTMLReport.

הם נבדלים מעט בהתאם למאפיינים הספציפיים הדרושים, כגון פורמט פלט ומטפלים בתמונות.

למעשה, מסמכי PDF מטמיעים תמונות יחד עם טקסט, בעוד שדוחות HTML צריכים ליצור אותם ו / או לקשר אותם.

לכן, פונקציית עיבוד ה- PDF פשוטה למדי:

חלל פרטי createPDFReport (דוח IReportRunnable, תגובה HttpServletResponse, HttpServletRequest בקשה) {IRunAndRenderTask runAndRenderTask = birtEngine.createRunAndRenderTask (דוח); response.setContentType (birtEngine.getMIMEType ("pdf")); אפשרויות IRenderOption = RenderOption חדש (); PDFRenderOption pdfRenderOption = PDFRenderOption חדש (אפשרויות); pdfRenderOption.setOutputFormat ("pdf"); runAndRenderTask.setRenderOption (pdfRenderOption); runAndRenderTask.getAppContext (). put (EngineConstants.APPCONTEXT_PDF_RENDER_CONTEXT, בקשה); נסה את {pdfRenderOption.setOutputStream (response.getOutputStream ()); runAndRenderTask.run (); } לתפוס (חריג e) {לזרוק RuntimeException חדש (e.getMessage (), e); } סוף סוף {runAndRenderTask.close (); }}

בעוד שפונקציית עיבוד ה- HTML זקוקה להגדרות נוספות:

חלל פרטי יוצר HTMLReport (דוח IReportRunnable, תגובה HttpServletResponse, בקשת HttpServletRequest) {IRunAndRenderTask runAndRenderTask = birtEngine.createRunAndRenderTask (דוח); response.setContentType (birtEngine.getMIMEType ("html")); אפשרויות IRenderOption = RenderOption חדש (); HTMLRenderOption htmlOptions = HTMLRenderOption חדש (אפשרויות); htmlOptions.setOutputFormat ("html"); htmlOptions.setBaseImageURL ("/" + reportsPath + imagesPath); htmlOptions.setImageDirectory (imageFolder); htmlOptions.setImageHandler (htmlImageHandler); runAndRenderTask.setRenderOption (htmlOptions); runAndRenderTask.getAppContext (). put (EngineConstants.APPCONTEXT_BIRT_VIEWER_HTTPSERVET_REQUEST, בקשה); נסה את {htmlOptions.setOutputStream (response.getOutputStream ()); runAndRenderTask.run (); } לתפוס (חריג e) {לזרוק RuntimeException חדש (e.getMessage (), e); } סוף סוף {runAndRenderTask.close (); }}

ראוי לציון, הגדרנו את HTMLServerImageHandler במקום לעזוב את מטפל ברירת המחדל. להבדל הקטן הזה יש השפעה רבה על הנוצר img תָג:

  • המטפל המוגדר כברירת מחדל מקשר בין img תג לנתיב מערכת הקבצים, חסום לאבטחה על ידי דפדפנים רבים
  • ה HTMLServerImageHandler קישורים לכתובת האתר של השרת

עם ה setImageDirectory בשיטה, אנו מציינים היכן המנוע ישמור את קובץ התמונה שנוצר.

כברירת מחדל, המטפל מייצר קובץ חדש בכל בקשה, כך נוכל להוסיף שכבת מטמון או מדיניות מחיקה.

8.3. פרסום התמונות

במקרה של דוח HTML, קבצי תמונות הם חיצוניים, ולכן עליהם להיות נגישים בנתיב השרת.

בקוד לעיל, עם setBaseImageURL אנו אומרים למנוע באיזה נתיב יחסי להשתמש img קישור תג, אז עלינו לוודא שהנתיב נגיש בפועל!

מסיבה זו, שלנו ReportEngineApplicationהגדרנו את אביב לפרסם את תמונות תיקיה:

@SpringBootApplication @EnableWebMvc class public ReportEngineApplication מיישם את WebMvcConfigurer {@Value ("$ {reports.relative.path}") דוחות מחרוזת פרטיים; @Value ("$ {images.relative.path}") imagesPath מחרוזת פרטית; ... @ ביטול ריק ריק ציבורי addResourceHandlers (הרישום ResourceHandlerRegistry) {הרישום .addResourceHandler (reportsPath + imagesPath + "/ **") .addResourceLocations ("file: ///" + System.getProperty ("user.dir") + " / "+ reportsPath + imagesPath); }}

לא משנה מה הדרך שנבחר, עלינו לוודא שאותו מסלול משמש כאן וגם ב html אפשרויות של הקוד הקודם, או שהדוח שלנו לא יוכל להציג תמונות.

9. הצגת הדוח

הרכיב האחרון הדרוש כדי להכין את היישום שלנו הוא בקר להחזרת התוצאה שניתנה:

@RequestMapping (method = RequestMethod.GET, value = "/ report / {name}") @ResponseBody public void createFullReport (HttpServletResponse response, HttpServletRequest request, @PathVariable ("name") שם מחרוזת, @RequestParam ("פלט") מחרוזת פלט) זורק EngineException, IOException {פורמט OutputType = OutputType.from (פלט); reportService.generateMainReport (שם, פורמט, תגובה, בקשה); }

עם ה תְפוּקָה פרמטר, אנו יכולים לאפשר למשתמש לבחור את הפורמט הרצוי - HTML או PDF.

10. בדיקת הדוח

אנו יכולים להתחיל את היישום על ידי הפעלת ה- ReportEngineApplication מעמד.

במהלך ההפעלה, ה- BirtReportService class יטען את כל הדוחות שנמצאו ב- /דיווחים תיקיה.

כדי לראות את הדוחות שלנו בפעולה, עלינו רק להפנות את הדפדפן שלנו ל:

  • / report / csv_data_report? output = pdf
  • / report / csv_data_report? output = html
  • / דוח / static_report? output = pdf
  • / report / static_report? output = html

הנה איך csv_data_report דוח נראה:

כדי לטעון מחדש דוח לאחר שינוי קובץ העיצוב, אנו פשוט מכוונים את הדפדפן אליו / דווח / טען מחדש.

11. מסקנה

במאמר זה שילבנו את BIRT עם Spring Boot, בחנו את המלכודות והאתגרים, אך גם את כוחו וגמישותו.

קוד המקור של המאמר זמין באתר GitHub.