{"id":15706779,"url":"https://github.com/michael-simons/enerko-reports2","last_synced_at":"2025-07-13T19:40:42.697Z","repository":{"id":57730406,"uuid":"10820758","full_name":"michael-simons/enerko-reports2","owner":"michael-simons","description":"ENERKOs Report Engine","archived":false,"fork":false,"pushed_at":"2015-08-04T13:12:59.000Z","size":7084,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-14T06:38:47.560Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/michael-simons.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"LICENSE-2.0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-06-20T13:50:09.000Z","updated_at":"2023-06-03T16:42:29.000Z","dependencies_parsed_at":"2022-09-26T22:01:24.321Z","dependency_job_id":null,"html_url":"https://github.com/michael-simons/enerko-reports2","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michael-simons%2Fenerko-reports2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michael-simons%2Fenerko-reports2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michael-simons%2Fenerko-reports2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michael-simons%2Fenerko-reports2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michael-simons","download_url":"https://codeload.github.com/michael-simons/enerko-reports2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249167812,"owners_count":21223574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T20:28:17.110Z","updated_at":"2025-04-15T23:19:10.093Z","avatar_url":"https://github.com/michael-simons.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ENERKOs Report Engine\n\n## Abstract\n\nENERKOs Report Engine is a [Apache POI-HSSF][1] based reporting engine that runs inside the JVM of an Oracle Datebase and creates Excel reports through an PL/SQL interface.\n\nIt is designed to provide an unified reporting engine for\n\n* Oracle Forms 6i based applications\n* Java SE clients as well as\n* Webapplications with different architectures.\n\nIt fits into 2-tier applications as well as into 3-tier applications as reports are stored at a central point (the database) as \n\n* PL/SQL functions\n* Queries or\n* views.\n\nIt consists of 2 parts:\n\n* The implementation in Java\n* An PL/SQL api to access the Java Stored Procedures\n\nENERKOs Report Engine can also run client side but this is not recommended as installation base will be duplicated.\n\nReports can be created from scratch or can be based on other Excel sheets named templates. Cell formating, formulas, macros and diagrams will be preserved. When opened in Excel, those diagrams and macros will be updated using the actual values.\n\nENERKOs Report Engine is used to create reports with over 50,000 cells, containing diagrams and more.\n\n## Requirements\n\nAt least an Oracle Database 11g Release 11.1.0.6.0 standard edition. This library isn't portable to other databases and completely Oracle specific. It should probably work in Standard Edition (One), but not in an Express Edition due the lack of an internal JVM.\n\n## Installation\n\nThe following describes the installation inside a database with the fictive user 'hre'.\n\nThe report engine should be installed into every scheme where it will be used.\n\nThe user needs the following privileges\n\n\tGRANT CREATE ANY PROCEDURE TO \"HRE\";\n\tGRANT CREATE ANY TABLE TO \"HRE\";\n\tGRANT CREATE PROCEDURE TO \"HRE\";\n\tGRANT CREATE TABLE TO \"HRE\";\n\nQuotas must be adapted or unlimited tablespace be granted:\n\n\tGRANT UNLIMITED TABLESPACE TO \"HRE\"\n\nTo actually load the java source files the following permission is needed as well:\n\n\tcall dbms_java.grant_permission('HRE', 'SYS:oracle.aurora.security.JServerPermission', 'loadLibraryInClass.*', null);\n\t\t\nI use [loadjava.bat][3] to load the java source files which is part of the Oracle Client package (Oracle InstantClient won't be enough). Alternatively [dbms_java.loadjava][4] can be used.\n\nFirst, load the required dependencies:\n\n\tloadjava.bat -user hre/hre@database -resolve lib/commons-codec-1.5.jar\n\tloadjava.bat -user hre/hre@database -resolve lib/poi-3.9.jar\n\t\nthen load ENERKOs Report Engine:\n\n\tloadjava.bat -user hre/hre@database -resolve target/enerko-reports2-0.0.1-SNAPSHOT.jar\n\t\nThe same using dbms_java (Please note that the file must exists on path reachable by the database process)\n\n\tset serveroutput on\n\tCALL dbms_java.set_output(3000);\n\tCALL dbms_java.loadjava('-resolve /var/tmp/enerko_reports/enerko-reports2-0.0.2-SNAPSHOT.jar');\n\nThen you need some SQL packages:\n\n\n    # A type that mimics a varg list\n\tsqlplus hre/hre@database \u003c src/main/sql/t_vargs.sql\n\t\n\t# The type that represents a cell definition\n\tsqlplus hre/hre@database \u003c src/main/sql/t_er_comment_definition.sql \n\tsqlplus hre/hre@database \u003c src/main/sql/t_er_cell_definition.sql \n\t# and the list thereof\n\tsqlplus hre/hre@database \u003c src/main/sql/table_of_er_cell_definitions.sql \n\t\n\t# And certainly the PL/SQL api:\n\tsqlplus hre/hre@database \u003c src/main/sql/pck_enerko_reports2.pks.sql\n\tsqlplus hre/hre@database \u003c src/main/sql/pck_enerko_reports2.pkb.sql\n\t\n\n## Usage\n\nThe BLOBs created by ENERKOs Report Engine can be used in many possible ways, they can be accessed by Java based webapplications through JDBC, by Forms etc.\n\nThe following examples assume a database directory called \"enerko_reports\" that is writable by the ENERKOs Report Engine user. To create this directory, grant the HRE user the following privileges: \n\n\tGRANT CREATE ANY DIRECTORY TO \"HRE\";\n\t\nand create the directory like this:\n\n\tCREATE DIRECTORY enerko_reports AS '/var/tmp/enerko_reports';\n\t\nor if the directoy already exists, grant read and writes to the report user:\n\n\tGRANT READ ON DIRECTORY enerko_reports TO \"HRE\";\n\tGRANT WRITE ON DIRECTORY enerko_reports TO \"HRE\";\n\t\nRead more about LOB handling [DBMS_LOB][5]. pck_enerko_reports2 contains  [UTL_FILE][6] based procedures / functions to store LOBs into files and read files into LOBs.\n\nAll reports presented are part of this project, have a look at src/test/sql/pck_enerko_reports2_test.sql.\n\t\n### Create a report using a simple statement\n\n#### Without templates\n\n\tDECLARE\n\t\tv_report BLOB;\n\tBEGIN\n\t\t-- Create the report\n\t\tv_report := pck_enerko_reports2.f_create_report_from_statement('Select ''s1'' as sheetname, 1 as cell_column, 1 as cell_row, ''c1'' as cell_name, ''string'' as cell_type, ''cv'' as cell_value from dual');\n\t\t\n\t\t-- Store it into a server side file\n\t\tpck_enerko_reports2.p_blob_to_file(v_report, 'enerko_reports', 'example1.xls');\n\tEND;\n\t/\n\t\n#### With templates\n\nThe template can be any blob containing a valid Excel sheet. The examples accesses a template inside a server side directory but any blob column will do.\n\n\tDECLARE\n\t\tv_template BLOB;\n\t\tv_report BLOB;\n\tBEGIN\n\t\tv_template := pck_enerko_reports2.f_file_to_blob('enerko_reports', 'template1.xls');\n\n\t\t-- Create the report\n\t\tv_report := pck_enerko_reports2.f_create_report_from_statement(\n\t\t\t'Select ''f_fb_report_source_test'' as sheetname, 0 as cell_column, 0 as cell_row, null as cell_name, ''string'' as cell_type, ''Hello, World'' as cell_value from dual',\n\t\t\tv_template\n\t\t);\n\t\n\t\t-- Store it into a server side file\n\t\tpck_enerko_reports2.p_blob_to_file(v_report, 'enerko_reports', 'example2.xls');\n\tEND;\n\t/\n\t\nIf a template contains sheets that should be visible to the user, they can be hidden or deleted through the use of special cells that don't appear in the final report. To hide a sheet use the following cell definition:\n\n\tt_er_cell_definition('__HIDE_SHEET__', 0, 0, 'string', 'hide_me') -- The sheet with the name \"hide_me\" will be hidden\n\t\nTo delete a sheet, use a cell like the following:\n\t\n\tt_er_cell_definition('__DELETE_SHEET__', 0, 0, 'string', 'delete_me') -- The sheet with the name \"delete_me\" will be deleted\n\t\nSheets can also be cloned. Be aware that this doesn't work with sheets containing charts (a runtime exception will be thrown):\n\n\tt_er_cell_definition('__CLONE_SHEET__\"clone_me\"_as_\"cloned_sheet\"', 0, 0, 'string', 'clone_me') -- The sheet with the name \"clone_me\" will be cloned as \"cloned_sheet\"\n\t\n### Create a report using pipelined functions\n\n#### Without templates\n\nPipelined functions are a very nice and handy feature of the Oracle database. Basically those are functions that can act as table in the from clause:\n\n\u003e Table functions are functions that produce a collection of rows (either a nested table or a varray) that can be queried like a physical database table. You use a table function like the name of a database table, in the FROM clause of a query.\n\nFrom [Using Pipelined and Parallel Table Functions][7]\n\nAt ENERKO pipelined functions are the main report source. Data can be selected in a PL/SQL method using standard SQL statements and than be arranged in arbitrary ways, incrementally building a report. Thus any developer with some SQL knowledge can create complex reports without overly complex queries or Java knowledge at all.\n\nThe test resources contain some very simple pipelined function based reports.\n\nHere is a an example to call this from PL/SQL. Notice the lack of vargs in PL/SQL and the record type of strings:\n\n\tDECLARE\n\t\tv_report BLOB;\n\tBEGIN\n\t\t-- Create the report\n\t\tv_report := pck_enerko_reports2.f_create_report(\n\t\t\t'pck_enerko_reports2_test.f_fb_report_source_test',\n\t\t\tt_vargs('10', '21.09.1979', 'Some label')\n\t\t);\n\t\n\t\t-- Store it into a server side file\n\t\tpck_enerko_reports2.p_blob_to_file(v_report, 'enerko_reports', 'example3.xls');\n\t\t\n\t\t-- Create a report without arguments\n\t\tv_report := pck_enerko_reports2.f_create_report('pck_enerko_reports2_test.f_noarg_report');\n\t\tpck_enerko_reports2.p_blob_to_file(v_report, 'enerko_reports', 'example4.xls');\n\tEND;\n\t/\n\t\n#### With templates\t\n\nReports based on pipelined functions works also with templates:\n\n\tDECLARE\n\t\tv_template BLOB;\n\t\tv_report BLOB;\n\tBEGIN\n\t\tv_template := pck_enerko_reports2.f_file_to_blob('enerko_reports', 'template1.xls');\n\n\t\t-- Create the report\n\t\tv_report := pck_enerko_reports2.f_create_report(\n\t\t\t'pck_enerko_reports2_test.f_fb_report_source_test',\n\t\t\tv_template,\n\t\t\tt_vargs('10', '21.09.1979', 'Some label')\n\t\t);\n\t\n\t\t-- Store it into a server side file\n\t\tpck_enerko_reports2.p_blob_to_file(v_report, 'enerko_reports', 'example5.xls');\n\t\t\n\t\t-- Create a report without arguments\n\t\tv_report := pck_enerko_reports2.f_create_report('pck_enerko_reports2_test.f_noarg_report', v_template);\n\t\tpck_enerko_reports2.p_blob_to_file(v_report, 'enerko_reports', 'example6.xls');\n\tEND;\n\t/\n\t\n### Evaluate Excel files and reports\n\nENERKOs Report Engine can evaluate Excel files and reports on-the-fly and present them as a virtual table in a from clause:\n\n#### Evaluate an Excel file\n\nThis creates an Excel workbook and pushes it back to the Reports Engine for on-the-fly evaluation. It also demonstrates how an Excel sheet can be queried through SQL. Furthermore it shows our extension NormInv to Apache HSSF. NormInv is a statistical function available in Office 2003 but not in Apache HSSF (you see the log message that the engine couldn't evaluate NormInv (B7), but only Enerko_NormInv (C7)):\n\n\tSET LINESIZE 300\n\tSELECT substr(cell_name,1,2) as name, to_number(cell_value, '9999D999999999999999999',  'nls_numeric_characters=''.,''') as value\n\tFROM table(\n\t\tpck_enerko_reports2.f_evaluate_workbook(\n\t\t\tpck_enerko_reports2.f_create_report(\n\t\t\t\t'pck_enerko_reports2_test.f_all_features', \n\t\t\t\tpck_enerko_reports2.f_file_to_blob('enerko_reports', 'template2.xls')\n\t\t\t)\n\t\t)\n\t) src \n\tWHERE sheetname = 'datatypes'\n\t  AND cell_name IN ('B7', 'C7');\n\nIt's certainly possible to evaluate random access files that are available as blobs somewhere:\n\t\t\n\tSELECT substr(cell_name,1,3) as name, substr(cell_value,1,10) as value\n\tFROM table(\n\t\tpck_enerko_reports2.f_evaluate_workbook(\n\t\t\tpck_enerko_reports2.f_file_to_blob('enerko_reports', 'random_worksheet.xls')\t\t\n\t\t)\n\t) src;\n\t\n#### Create and evaluate reports without storing them\n\nAll examples above showing how to create and store reports as Excel files can be rewritten to evaluate them immediately:\n\nEvaluating a statement based report:\n\n\tSELECT substr(cell_name,1,3) as name, substr(cell_value,1,16) as value, substr(src.cell_comment.comment_text,1,32) as cell_comment\n\tFROM table(\n\t\tpck_enerko_reports2.f_eval_report_from_statement(\n\t\t\t'Select ''f_fb_report_source_test'' as sheetname, 0 as cell_column, 0 as cell_row, null as cell_name, ''string'' as cell_type, ''Hello, World'' as cell_value from dual',\n\t\t\tpck_enerko_reports2.f_file_to_blob('enerko_reports', 'template1.xls') -- \u003c- can also be null\n\t\t)\n\t) src;\n\nand a function based report\n\n\tSELECT substr(sheetname,1,20) as sheet, substr(cell_name,1,3) as name, substr(cell_value,1,16) as value\n\tFROM table(\n\t\tpck_enerko_reports2.f_eval_report(\n\t\t\t\t'pck_enerko_reports2_test.f_fb_report_source_test',\n\t\t\t\tpck_enerko_reports2.f_file_to_blob('enerko_reports', 'template1.xls'),\n\t\t\t\tt_vargs('10', '21.09.1979', 'Some label')\n\t\t)\n\t) src;\n\t\n\tSELECT substr(sheetname,1,20) as sheet, substr(cell_name,1,3) as name, substr(cell_value,1,16) as value\n\tFROM table(\n\t\tpck_enerko_reports2.f_eval_report(\n\t\t\t\t'pck_enerko_reports2_test.f_all_features',\n\t\t\t\tpck_enerko_reports2.f_file_to_blob('enerko_reports', 'template2.xls'),\n\t\t\t\tnull\n\t\t)\n\t) src;\n\t\n## API\n\nThe main structure for creating reports is the cell definition t_er_cell_definition:\n\n\tSQL\u003e desc t_er_cell_definition\n\t  Name                                      Null?    Typ\n\t  ----------------------------------------- -------- ----------------------------\n\t  SHEETNAME                                          VARCHAR2(512)\n\t  CELL_COLUMN                                        NUMBER(38)\n\t  CELL_ROW                                           NUMBER(38)\n\t  CELL_NAME                                          VARCHAR2(64)\n\t  CELL_TYPE                                          VARCHAR2(512)\n\t  CELL_VALUE                                         VARCHAR2(32767)\n\t  CELL_COMMENT                                       T_ER_COMMENT_DEFINITION\n\n| Attribute      | Meaning                                                         |\n|----------------|-----------------------------------------------------------------|\n| SHEETNAME      | Name of the worksheet                                           |\n| CELL_COLUMN    | 0-based column index                                            |\n| CELL_ROW       | 0-based row index                                               |\n| CELL_NAME      | Cell reference, only used for output, can be null               |\n| CELL_TYPE      | Valid datatype (see \"Supported datatypes for cell definitions\") |\n| CELL_VALUE     | String representation of the concrete cell                      |\n| CELL_COMMENT   | An optional comment that is added to the specified cell         |\n\t\t\nReports can be created either using SQL statements returning the columns mentioned here or pipelined functions returning this type in the pipe. Thus, all cells can be filled in arbitrary order.\t\t\n\nCells can contain Excel comments which are defined through t_er_comment_definition:\n\n\tSQL\u003e desc T_ER_COMMENT_DEFINITION\n\t Name\t\t\t\t\t   Null?    Typ\n\t ----------------------------------------- -------- ----------------------------\n\t COMMENT_TEXT\t\t\t\t\t    VARCHAR2(32767)\n\t COMMENT_AUTHOR \t\t\t\t    VARCHAR2(32767)\n\t COMMENT_COLUMN \t\t\t\t    NUMBER(38)\n\t COMMENT_ROW\t\t\t\t\t    NUMBER(38)\n\t COMMENT_WIDTH\t\t\t\t\t    NUMBER(38)\n\t COMMENT_HEIGHT \t\t\t\t    NUMBER(38)\n\t COMMENT_VISIBLE\t\t\t\t    VARCHAR2(8)\n\n| Attribute      | Meaning                                                         |\n|----------------|-----------------------------------------------------------------|\n| COMMENT_TEXT   | The text of the comment                                         |\n| COMMENT_AUTHOR | The author of the comment (defaults to the database user)\t   |\n| COMMENT_COLUMN | 1-based column, defaults to the column of the cell + 1          |\n| COMMENT_ROW\t | 1-based row, defaults to the row of the cell                    |\n| COMMENT_WIDTH\t | Width of the comment, default 1                                 |\n| COMMENT_HEIGHT | Height of the comment, default 1                                |\n| COMMENT_VISIBLE| Flag, if the comment is visible, default 'false'                |\n\n\nYou can manually assign a comment to an existing t_er_cell_definition object or use one of the provided constructors, either using a plain string or a complete t_er_comment_definition object:\n\n\tFUNCTION f_fb_report_source_test2 RETURN table_of_er_cell_definitions pipelined IS\n\tBEGIN\t\t    \n\t    pipe row(t_er_cell_definition(\n\t        's1', 1, 1, null, 'string', 'beliebiger string wert', 'mit einem beliebigen Kommentar'\n\t    ));\n\t    pipe row(t_er_cell_definition(\n\t        's1', 1, 2, null, 'string', 'beliebiger string wert', \n\t        t_er_comment_definition(\n\t            'test', p_column =\u003e 23, p_row =\u003e 42, p_width =\u003e 3, p_height =\u003e 4, p_visible =\u003e 'true'\n\t        )\n\t    ));\n\tEND f_fb_report_source_test2;\n \nYou'll find more examples in the test package pck_enerko_reports2_test.\n\t\t\n### Options and formatting\n\nThe pck_enerko_reports2_test.f_all_features shows pretty much all features:\n\n\tDECLARE\n\t\tv_template BLOB;\n\t\tv_report BLOB;\n\tBEGIN\n\t\tv_template := pck_enerko_reports2.f_file_to_blob('enerko_reports', 'template2.xls');\n\t\tv_report := pck_enerko_reports2.f_create_report('pck_enerko_reports2_test.f_all_features', v_template);\n\n\t\tpck_enerko_reports2.p_blob_to_file(v_report, 'enerko_reports', 'example7.xls');\n\tEND;\n\t/\n\t\nThe following features are available and the following formatting is possible:\n\n#### Supported datatypes for function arguments\n\n| name (as in PL/SQL type name) | format                                  |\n|:-------------------------------|:---------------------------------------|\n| varchar2                      | free format                             |\n| number                        | with nls_numeric_characters set to '.,' |\n| date                          | DD.MM.YYYY                              |\n| timestamp                     | DD.MM.YYYY HH24:MI'                     |\n\nThe arguments are passed as varchar2s to the report engine so the format must be valid. Otherwise the report generation will fail with a ParseException.\n\n#### Supported datatypes for cell definitions\n\n| Name     | format                                  |\n|:---------|:----------------------------------------|\n| string   | free format                             |\n| number   | with nls_numeric_characters set to '.,' |\n| date     | DD.MM.YYYY                              |\n| datetime | DD.MM.YYYY HH24:MI'                     |\n| formula  | i.e. SUM(B23:B42)                       |\n\nNumeric values can add a format specification according to [\"Including decimal places and significant digits\"][8] by separating it with a double '@@' from the value:\n\n\t42.23@@#0.000\n\t\nFormulas are noted without the leading '=', cell reference is the known excel notation A1 … Zn. \n\n#### Format templates / reference cells\n\nENERKOs Report Engine supports templates not only for formatting but also as a reference. The user can create an (invisible) sheet with formatting templates for dates, numbers etc.\n\nThose references can be addressed through the data type with the following form:\n\n\tdatetime; \"reference_sheet\" B1\n\tdate; \"reference_sheet\" B2\n\tnumber; \"reference_sheet\" A1\n\t\nOr abstract:\n\t\n\tdatatype; \"Name of the worksheet\" CELLREFERENCE\n\t\nAny non empty, formatted cell at the reference will be used to format the current cell.\n\nThis can be used for user defined date formats for example.\n\n[1]: http://poi.apache.org/spreadsheet/\n[2]: http://docs.oracle.com/cd/E11882_01/java.112/e10588/toc.htm\n[3]: http://docs.oracle.com/cd/E11882_01/java.112/e10588/cheleven.htm#JJDEV10060\n[4]: http://docs.oracle.com/cd/E11882_01/java.112/e10588/appendixa.htm#JJDEV13000\n[5]: http://docs.oracle.com/cd/E11882_01/appdev.112/e10577/d_lob.htm\n[6]: http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/u_file.htm#ARPLS70896\n[7]: http://docs.oracle.com/cd/E11882_01/appdev.112/e10765/pipe_paral_tbl.htm\n[8]: http://office.microsoft.com/en-us/excel-help/number-format-codes-HP005198679.aspx","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichael-simons%2Fenerko-reports2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichael-simons%2Fenerko-reports2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichael-simons%2Fenerko-reports2/lists"}