用一个程序生成另一个程序_还有另一个报告生成器?
用一個程序生成另一個程序
如果您具有業(yè)務應用程序開發(fā)的經驗,那么很可能會遇到要求該應用程序具有靈活的報告機制的需求。 我工作的公司主要專注于開發(fā)業(yè)務解決方案,而報告是必不可少的,實際上,它必須包含我們開發(fā)的所有企業(yè)系統(tǒng)的方面。 為了在我們的系統(tǒng)中實現靈活的報告,我們開發(fā)了自己的開源報告生成器-YARG (又一次獲得了另一個報告生成器)(以Apache 2.0許可分發(fā))。 現在,YARG是CUBA平臺報告的核心-CUBA 平臺本身就是我們開發(fā)的所有系統(tǒng)的基礎。
為什么需要開發(fā)一個新的
首先,讓我指出我們不是車輪發(fā)明家。 只要這些解決方案適合我們,我們就一直在尋找與之集成的解決方案。 不幸的是,在這種情況下,我們找不到符合我們確定的以下要求的任何開源工具:
- 以模板格式生成報告和/或將輸出轉換為PDF
- 避免使用外部工具來創(chuàng)建報告模板(Microsoft Office或Libreoffice應該足夠了)
- 支持各種格式的模板: DOC,ODT,XLS,DOCX,XLSX,HTML
- 能夠將復雜的XLS和XLSX模板與圖表,公式等配合使用。
- 能夠使用HTML布局和插入/嵌入圖像
- 拆分出數據層(報告結構和數據獲取)和表示層(報告模板)
- 啟用各種數據獲取方法,例如SQL,JPQL或Groovy腳本
- 與IoC框架( Spring , Guice )集成的能力
- 將該工具用作獨立應用程序的功能,以便能夠在Java生態(tài)系統(tǒng)之外使用它(例如,使用PHP生成報告)
- 以透明XML格式存儲報告結構
我們可以找到的最接近的工具是JasperReports ,但是有一些阻止程序使我們無法使用它:
- 免費版本無法生成DOC報告(有一個提供此功能的商業(yè)庫)
- XLS報告非常有限,無法使用圖表,公式和單元格格式
- 要創(chuàng)建報告,必須具有一定的技能和知識,以及如何使用非常特定的工具(例如iReports )
- 數據層和表示層之間沒有明確的分隔
當然,我們研究了許多其他不同的工具,但是我們發(fā)現的所有其他庫都集中在某種特定格式上。 我們希望有一個萬能的報表功能-一種用于所有報表的工具。
考慮到以上列出的所有觀點和想法,我們決定開發(fā)另一種定制的報告生成工具。
什么是內幕
當我們開始YARG時,找到用于XLS集成的庫( POI-HSSF , JXLS等)不是問題。 我們決定選擇Apache POI作為最受歡迎和受支持的庫。
DOC集成的情況則完全相反。 在開源市場上只有很少的選擇( POI-HWPF , COM和UNO Runtime )。 POI-HWPF庫在許多方面都非常有限,我們認為它不是合適的選擇。 我們必須在COM和UNO運行時之間進行選擇,這實際上是用于OpenOffice服務器端集成的API。
因此,經過深入調查,我們決定選擇UNO Runtime ,主要是因為成功將其用于以完全不同的語言(例如Python,Ruby,C#等)編碼的系統(tǒng)的人們的積極反饋。
盡管POI-HSSF的使用非常簡單(圖表除外),但我們在集成UNO Runtime時面臨許多挑戰(zhàn):
后來,當DOCX4J庫變得非常成熟和流行時,我們支持XLSX / DOCX。 DOCX4J庫的主要優(yōu)點是,它提供了對文檔結構的必要的低級訪問(基本上,您使用XML進行操作)。 使用DOCX4J的另一個好處是,它不需要OpenOffice服務器集成即可生成DOCX報告。
另外,還可以使用帶有Freemarker標記的文檔作為報告模板。 我們通常使用它生成非常自定義的HTML報表,然后將結果轉換為PDF 。
最后,YARG基礎結構是以可擴展的方式開發(fā)的,因此有經驗的用戶可以自己實現與任何其他模板類型的集成。
你好世界報告
讓我們認識一下YARG。 報告生成器的主要思想是將數據層和表示層分開。 數據層使腳本編制或直接SQL查詢能夠獲取所需的信息,而表示層則代表所獲取數據的標記。
YARG的所有報告均由所謂的“樂隊”組成 。 帶是將數據和表示層鏈接在一起的東西。 因此,每個樂隊都知道從何處獲取數據以及將數據放置在模板中的位置。
例如,我們想將所有員工打印到Excel電子表格中。 我們將需要創(chuàng)建“ Staff”樂隊并定義一個SQL查詢以獲取員工列表:
select name, surname, position from staffJava代碼
ReportBuilder reportBuilder = new ReportBuilder(); ReportTemplateBuilder reportTemplateBuilder = new ReportTemplateBuilder().documentPath("/home/haulmont/templates/staff.xls").documentName("staff.xls").outputType(ReportOutputType.xls).readFileFromPath(); reportBuilder.template(reportTemplateBuilder.build()); BandBuilder bandBuilder = new BandBuilder(); ReportBand staff= bandBuilder.name("Staff").query("Staff", "select name, surname, position from staff", "sql").build(); reportBuilder.band(staff); Report report = reportBuilder.build();Reporting reporting = new Reporting(); reporting.setFormatterFactory(new DefaultFormatterFactory()); reporting.setLoaderFactory(new DefaultLoaderFactory().setSqlDataLoader(new SqlDataLoader(datasource)));ReportOutputDocument reportOutputDocument = reporting.runReport(new RunParams(report), new FileOutputStream("/home/haulmont/reports/staff.xls"));剩下的唯一事情就是創(chuàng)建XLS模板:
開始了! 只需運行該程序即可享受結果!
沒有Java的進階范例
假設我們有一個書店網絡。 需要生成一個XLS報告,其中顯示了已售書的列表,并參考了售書的書店。 此外,我們沒有Java開發(fā)人員,只有擁有XML和SQL基本技能的系統(tǒng)管理員。
首先,我們需要為報告創(chuàng)建XLS模板:
如您所見,我們定義了兩個命名區(qū)域(對應于樂隊):商店(藍色)和書籍實例(白色)。
現在,我們必須從數據庫中獲取所需的數據:
select shop.id as "id", shop.name as "name", shop.address as "address" from store shopselect book.author as "author", book.name as "name", book.price as "price", count(*) as "count" from book book where book.store_id = ${Shop.id} group by book.author, book.name, book.price最后,我們使用XML聲明報告的波段結構:
<?xml version="1.0" encoding="UTF-8"?> <report name="report"><templates><template code="DEFAULT" documentName="bookstore.xls" documentPath="./test/sample/bookstore/bookstore.xls" outputType="xls" outputNamePattern="bookstore.xls"/></templates><rootBand name="Root" orientation="H"><bands><band name="Header" orientation="H"/><band name="Shop" orientation="H"><bands><band name="Book" orientation="H"><queries><query name="Book" type="sql"><script>select book.author as "author", book.name as "name", book.price as "price", count(*) as "count" from book where book.store_id = ${Shop.id} group by book.author, book.name, book.price</script></query></queries></band></bands><queries><query name="Shop" type="sql"><script>select shop.id as "id", shop.name as "name", shop.address as "address" from store shop</script></query></queries></band></bands><queries/></rootBand> </report>讓我們啟動報告并查看結果(下面的“ 獨立”部分描述了如何運行報告):
該用例表明,您可以引用父帶:book.store_id = $ {Shop.id}。 這使我們能夠過濾每個特定書店出售的書籍。
一個更高級的例子
現在,我們創(chuàng)建一個發(fā)票報告。 我們將創(chuàng)建DOCX文檔,然后將其轉換為不可變形式– PDF文檔。 為了說明如何加載數據的另一種方式,我們將使用groovy腳本,而不是直接SQL查詢:
<?xml version="1.0" encoding="UTF-8"?> <report name="report"><templates><template code="DEFAULT" documentName="invoice.docx" documentPath="./test/sample/invoice/invoice.docx" outputType="pdf" outputNamePattern="invoice.pdf"/></templates><formats><format name="Main.date" format="dd/MM/yyyy"/><format name="Main.signature" format="${html}"/></formats><rootBand name="Root" orientation="H"><bands><band name="Main" orientation="H"><queries><query name="Main" type="groovy"><script>return [['invoiceNumber':99987,'client' : 'Google Inc.','date' : new Date(),'addLine1': '1600 Amphitheatre Pkwy','addLine2': 'Mountain View, USA','addLine3':'CA 94043','signature':<![CDATA['<html><body><b><font color="red">Mr. Yarg</font></b></body></html>']]>]]</script></query></queries></band><band name="Items" orientation="H"><queries><query name="Main" type="groovy"><script>return [['name':'Java Concurrency in practice', 'price' : 15000],['name':'Clear code', 'price' : 13000],['name':'Scala in action', 'price' : 12000]]</script></query></queries></band></bands><queries/></rootBand> </report>您可能已經注意到,Groovy腳本返回List <Map <String,Object >>對象。 因此,每個項目都表示為一個鍵(參數名稱)和值(參數值)。
最后,我們將需要創(chuàng)建一個DOCX模板:
要將底部表格鏈接到書籍列表,我們使用## band = Items標記。
生成報告后,我們得到以下輸出:
IoC框架集成
如前所述,要求之一是提供集成到IoC框架( Spring , Guice )的能力。 我們將YARG用作CUBA平臺(我們用于企業(yè)應用程序開發(fā)的高級Java框架)中強大的報告引擎的一部分。 CUBA采用Spring作為IoC機制,讓我們看一下YARG如何集成到平臺中:
<bean id="reporting_lib_Scripting" class="com.haulmont.reports.libintegration.ReportingScriptingImpl"/> <bean id="reporting_lib_GroovyDataLoader" class="com.haulmont.yarg.loaders.impl.GroovyDataLoader"><constructor-arg ref="reporting_lib_Scripting"/> </bean> <bean id="reporting_lib_SqlDataLoader" class="com.haulmont.yarg.loaders.impl.SqlDataLoader"><constructor-arg ref="dataSource"/> </bean> <bean id="reporting_lib_JpqlDataLoader" class="com.haulmont.reports.libintegration.JpqlDataDataLoader"/> <bean id="reporting_lib_OfficeIntegration"class="com.haulmont.reports.libintegration.CubaOfficeIntegration"><constructor-arg value="${cuba.reporting.openoffice.path?:/}"/><constructor-arg><list><value>8100</value><value>8101</value><value>8102</value><value>8103</value></list></constructor-arg><property name="displayDeviceAvailable"><value>${cuba.reporting.displayDeviceAvailable?:false}</value></property><property name="timeoutInSeconds"><value>${cuba.reporting.openoffice.docFormatterTimeout?:20}</value></property> </bean> <bean id="reporting_lib_FormatterFactory"class="com.haulmont.yarg.formatters.factory.DefaultFormatterFactory"><property name="officeIntegration" ref="reporting_lib_OfficeIntegration"/> </bean> <bean id="reporting_lib_LoaderFactory" class="com.haulmont.yarg.loaders.factory.DefaultLoaderFactory"><property name="dataLoaders"><map><entry key="sql" value-ref="reporting_lib_SqlDataLoader"/><entry key="groovy" value-ref="reporting_lib_GroovyDataLoader"/><entry key="jpql" value-ref="reporting_lib_JpqlDataLoader"/></map></property> </bean> <bean id="reporting_lib_Reporting" class="com.haulmont.yarg.reporting.Reporting"><property name="formatterFactory" ref="reporting_lib_FormatterFactory"/><property name="loaderFactory" ref="reporting_lib_LoaderFactory"/> </bean>為了將YARG集成到Spring Framework中,應注冊以下bean:
如您所見,YARG可以輕松地嵌入到您的應用程序中。
獨立使用
YARG的另一個重要功能是可以用作獨立應用程序。 從技術上講,如果已安裝JRE,則可以從命令提示符下運行報告生成器。 例如,如果您有服務器端PHP應用程序,并且想在應用程序中啟用報告,則只需創(chuàng)建一個XLS模板,以XML聲明報告結構,然后從命令提示符下啟動YARG:
yarg -rp ~/report.xml -op ~/result.xls “-Pparam1=20/04/2014”CUBA平臺提供的更多功能
YARG已深度集成到CUBA平臺中,并充當該平臺中實現的強大報告機制的核心引擎。
首先,您可以使用CUBA Studio一鍵式嵌入報告( 此處提供只讀演示版):
CUBA為報表管理提供了方便的用戶界面:
- 報告瀏覽器,帶有導入/導出和運行報告的選項。
- 報告編輯器允許您創(chuàng)建任何復雜性的報告(定義帶,輸入參數,管理模板,使用Groovy,SQL和JPQL選擇數據):
- CUBA引入了報告向導功能。 借助向導,即使對編程的了解有限,任何用戶都可以快速創(chuàng)建報告:
總結這篇文章,讓我跳過通常無聊的深層思考(特別是因為可以在此處找到所有信息),并提出了一些我最喜歡的報告:
因此,如果您有興趣,請點擊鏈接并了解更多信息! 請注意,YARG是完全免費的,可以在GitHub上使用 。
翻譯自: https://www.javacodegeeks.com/2015/09/yet-another-report-generator.html
用一個程序生成另一個程序
總結
以上是生活随笔為你收集整理的用一个程序生成另一个程序_还有另一个报告生成器?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓开发需要掌握哪些技术(安卓开发需要)
- 下一篇: java使用泛型后消除泛型_如何以及何时