Sign In  Sign Up Live-Chat

George Kahn

  • Aspose.Report 1.1.2 Released

    Dear Customers,

    We have released Aspose.Report 1.1.2

    Added: A new dialog in visual designer to allow user create the database connection string.
    Added: Enhancement to visual designer for ensure user input multiple lines of value to any report parameter.

    Fixed: a bug about the unstallation of old version will remove the dynamic data item types user input inside the visual designer.

  • The visual demonstration for Aspose.Report design tool is available

    Considering some clients find difficult to understand how Aspose.Report design tool works, we provide a couple of flash pages to demonstrate entire reports making process, please go to apose.report wiki to check it out. 

    http://www.aspose.com/Wiki/default.aspx/Aspose.Report/Homepage.html

  • Aspose.Report 1.1.0 released

    Added :

    • Allow user to define and update the data item types with a data item type editor without programming.

    http://www.aspose.com/wiki/default.aspx/Aspose.Report/DataItemTypeEditor.html

    • Generates the code dynamically for the data item types inserted by the data item type editor when building the report.
    • Compiles and loads the assembly dynamically for the data item types inserted by the data item type editor when building the report.
    • The data type of attributes of each data item type in attribute editor will be appeared at the right description panel.

    Fixed :

    •  Sometimes not all of attributes of each data item type can be appeared in attribute editor.

     

     

     

  • Aspose.Report 1.0.2 released

    Dear Customers,

    We have released Aspose.Report 1.0.2.

    1. Added the feature that allows adding the page break into spreadsheet
    2. Added the feature that allows changing font color in spreadsheet editor
    3. Added the feature that allows saving a SQL script generated by a report action into a report parameter.
    4. Added the feature that allows importing the result of query into data item set
    5. Added some instruction inside the designer so user can understand the feature easily.
    6. Added a new attribute if-condition to Dynamic band by which the changes to Band would be only applied for the cells that satisfy the condition.
    7. Added the feature that ensures specifying some attributes of Dynamic Band to add and delete the columns & rows inside the spreadsheet during report building time.
    8. Added reminder message when overwrite existed file
    9. Added a new function GetCellValue for getting the value of a specified cell in output excel during report building time.
  • Aspose.Report 1.0.0 Released

    Dear Customers,

    We have released
    Aspose.Report1.0.0.  The following is its brief introduction.

    Unlike most of reporting tools in the market right now, Aspose.Report is focusing on separating the task between business analysts and developers, we realized that entire report design process is an assembly work, it requires the effort of both business analysts and developers, since no too many developers could understand the business logic very well while the business analysts rarely know the technology, and the reporting system is the most frequent changed module inside a information system, all of these factors cause lots of communication and come-back been happened between business analysts and developers during the report design process.

    With Aspose.Report, we could break down a report design process into different section so that business analysts and developers (or DBA) can work on different parts, for instance, developer could use SQL editor to compose dynamic SQL script and retrieve data (The good understanding to SQL and database is a success key for all of good reporting system), and business analysts could amend the report format layout so as to make it more suitable for business needs. Even further, the developers can boil down complex server-side database behaviors into simple and easy-to-use elements or functions that business analysts can easily incorporate into their reports.

    Aspose.Report includes a visual report design tool and an application development interface library, it adopts RDL (Report definition language) script as contract to connect the visual design tool to API library, business analysts can use visual design tool to edit RDL script and build the report, and the developers can reference API library in their own report building application to load RDL script and build report as well. So Aspose.Report will eliminate the boundary between business analysts and developers, speed up the report design process, and reduce the enterprise cost.

     

     

  • The Aspose.Report preview edition is out

    The Aspose.Report preview edition is out, please get a copy at http://www.aspose.com/Products/aspose.report/Aspose.Report.zip , and read the readme.txt before using it.

    If you have any question or comment, please mail to report@aspose.com or post to http://www.aspose.com/forums/ShowForum.aspx?ForumID=219 , thanks very much.

  • Aspose.Report - Some advanced features for RDL element

    As we know, most of business reports are not just based on a static SQL script, they will be varied by different situation such as field column or filter, our RDL element class model allow user to create their own data type and bind the data with our existed report element type. The following is the sample RDL script.

     <?xml version="1.0"?>
     <report name="TestDataBinding" startaction="define_data">
       <reportparameter id="sql.table.name" value="product" />
       <reportaction name="define_data" nextaction="generate_sql">
          <dataitemset id="sql.fields">
             <sqlfield id="sql.fields.1" field="category_name" alias="cat" />
             <sqlfield id="sql.fields.2" field="brand_name" alias="brand" />
             <sqlfield id="sql.fields.3" field="upc_id" alias="UPC" />
          </dataitemset>
       </reportaction>
    
    
       <reportaction name="generate_sql" nextaction="format_report">
          <sqlitem root="true">
             <sqlitem begin="select ">
                <reportparameter id="sql.comma" value="" />
                <foreach item="DataItems" variable="sql.fields.counter">
                   <dataitems refid="sql.fields" />
                   <sqlitem text="${sql.comma}" />
                   <sqlitem>
                      <binding sourceid="sql.fields" sourceprop="field" targetprop="text" index="${sql.fields.counter}" />
                   </sqlitem>
                   <sqlitem text=" as " />
                   <sqlitem>
                      <binding sourceid="sql.fields" sourceprop="alias" targetprop="text" index="${sql.fields.counter}" />
                   </sqlitem>
                   <reportparameter id="sql.comma" value=", " />
                </foreach>
             </sqlitem>
             <sqlitem text="from ${sql.table.name}" newline="true" />
             <sqlitem text=" order by 1" />
          </sqlitem>
       </reportaction>
    
    
       <reportaction name="format_report">
          <reportitem label="${sql.table.name}">
             <foreach item="DataItems" variable="sql.fields.counter">
                <dataitems refid="sql.fields" />
                <reportitem>
                   <binding sourceid="sql.fields" sourceprop="alias" targetprop="label" index="${sql.fields.counter}" />
                </reportitem>
             </foreach>
          </reportitem>
       </reportaction>
     </report>
    
    
    
    
    

    And here is log output.

        SqlItem output
    
    
            select category_name as cat, brand_name as brand, upc_id as UPC
    
    
            from product order by 1
    
    
          ReportItem output
    
    
             left:0; top:0; width:0; height:0 - (0)brand
    
    
             left:0; top:0; width:0; height:0 - (0)UPC
    
    
             left:0; top:0; width:0; height:0 - (0)product
    
    
    

    Instead of specifiying the customized data types in DataItemSet inside the RDL script, the framework also provide the development API extension to allow developers to write their own functions that could load their own data types into DataItemSet from the database or file and compile the data types and functions into a standalone library.

     <dataitemset id="sql.fields" loadfunc="${sqlfield::insert-fields()}" />

    Our RDL element class model provide the support for embedding a RDL script file into another RDL script file, user will benefit from it by sharing the reporting logic among different reports, such as a set of RDL to retrieve the definition from user data dictionary or define the report layout style. The following is the sample RDL script.

     <?xml version="1.0"?>
     <report name="TestNestedReport" startaction="gather_data" >
       <reportparameter id="global.var1" value="test_subreport1" />
       <reportparameter id="global.var2" value="test_subreport2" />
    
    
       <reportaction name="gather_data" nextaction="format_report">
         <rdl startaction="subreport2">
                <reportfiles>
                    <include name="E:\\reporttools\\data\\SubNestedReport1.RDL" />
                </reportfiles>
            </rdl>
       </reportaction>
    
    
       <reportaction name="format_report">
         <log message="format_report" level="Debug" />
       </reportaction>
     </report>
    
  • Aspose.Report - How RDL define the report layout

    Inside the last post, I introduced how RDL deal with procedural flow and macro variables, the following is another sample that illuminates how RDL handle the report layout.

     <?xml version="1.0"?>
     <report name="TestReportItemlayout" startaction="format_report" librarydir="E:\reporttools\src\Aspose\ReportTools\ReportTools.RDLElement\bin\Debug">
       <reportaction name="format_report">
          <log message="format report!" level="Debug" />
          <reportparameter name="body.top" value="5" />
          <reportparameter name="body.left" value="5" />
          <reportparameter name="row.height" value="10" />
          <reportparameter name="column.width" value="50" />
          <reportparameter name="header.height" value="25" />
          <reportparameter name="footer.height" value="30" />
          <reportparameter name="body.column.count" value="0" />
    
    
          <reportitem left="${body.left}" top="${body.top}" label="mainpage">
             <reportitem height="${header.height}" label="header">
                <reportitem left="${int::parse(column.width) * rdl::get-zindex()}" width="${column.width}" height="${header.height}" label="${'column' + int::to-string(rdl::get-zindex())}" />
    
    
                <reportparameter name="body.column.count" value="${int::parse(body.column.count) + 1}" />
    
    
                <reportitem left="${int::parse(column.width) * rdl::get-zindex()}" width="${column.width}" height="${header.height}" label="${'column' + int::to-string(rdl::get-zindex())}" />
    
    
                <reportparameter name="body.column.count" value="${int::parse(body.column.count) + 1}" />
    
    
                <reportparameter name="body.width" value="${int::parse(column.width) * int::parse(body.column.count)}" />
             </reportitem>
    
    
             <reportitem top="${header.height}" width="${body.width}" label="body">
                <foreach item="IntLoop" in="0,5" delim="," variable="row.counter">
                   <reportitem top="${int::parse(row.height) * int::parse(row.counter)}" height="${row.height}" width="${body.width}" label="${'row' + row.counter}" />
    
    
                   <reportparameter name="body.row.count" value="${int::parse(row.counter) + 1}" />
                </foreach>
    
    
                <reportparameter name="body.height" value="${int::parse(row.height) * int::parse(body.row.count)}" />
             </reportitem>
    
    
             <reportitem top="${int::parse(body.height) + int::parse(header.height)}" width="${body.width}" height="${footer.height}" label="footer" />
          </reportitem>
       </reportaction>
     </report>
    
    
    

    And the here is log output.

     left:5; top:5; width:0; height:0 - (0)mainpage
     left:5; top:5; width:0; height:25 - (0)header
     left:5; top:5; width:50; height:25 - (0)column0
     left:55; top:5; width:50; height:25 - (1)column1
     left:5; top:30; width:100; height:0 - (1)body
     left:5; top:30; width:100; height:10 - (0)row0
     left:5; top:40; width:100; height:10 - (0)row1
     left:5; top:50; width:100; height:10 - (0)row2
     left:5; top:60; width:100; height:10 - (0)row3
     left:5; top:70; width:100; height:10 - (0)row4
     left:5; top:80; width:100; height:10 - (0)row5
     left:5; top:90; width:100; height:30 - (2)footer
    
    
    

    As we can see above, reportitem is a basis RDL element type for report visual element such as Text, Box, or Line... it has some attribute about the layout and position such as Top, Left, Width and Style. Every reportitem is capable to contain a set of child elements, and child elements will be inherited some attributes from their container such as position or style.

    Another thing I 'd like to point out is that RDL supports custom functions and formulas, they are provided for some complex functionality such as calculating the element position or specifying the data binding between the RDL elements and domain objects.

  • Aspose.Report - A unit test case for RDL element types

    The following is RDL script used by one of unit test cases.

     <?xml version="1.0"?>
     <report name="Simple" startaction="prepare_query"  librarydir="E:\reporttools\src\Aspose\ReportTools\ReportTools.RDLElement\bin\Debug">
       <variable name="var_action_1" value="gather_data" />
       <variable name="var_action_2" value="format_report" />
       <reportaction name="prepare_query" nextaction="check_sql" description="generate the Sql script for reports">
          <log message="generate the SQL for report query!" level="Debug" />
     <!-- Putting the RDL elements that are used for specifying or assembling the SQL script here -->
          <variable name="action_result" value="good" />
          <if condition="${action_result=='bad'}">
             <variable name="var_action_1" value="done" />
          </if>
       </reportaction>
       <reportaction name="check_sql" nextaction="${var_action_1}">
          <log message="the SQL is ${action_result}, so next action is ${var_action_1}!" level="Debug" />
       </reportaction>
       <reportaction name="gather_data" nextaction="${var_action_2}">
          <log message="gather the data for report, its next action is ${var_action_2}!" level="Debug" />
     <!-- Putting the RDL elements that are used for retrieving the data here -->
       </reportaction>
       <reportaction name="format_report" nextaction="done">
          <log message="format report!" level="Debug" />
     <!-- Putting the RDL elements that are used for specifying the output type and layout here-->
       </reportaction>
       <reportaction name="done">
          <log message="Done!" level="Debug" />
       </reportaction>
     </report>
    
    
    
    
    

    And here is the log information produced by this test case.

                   First action specified: prepare_query 
                   prepare_query:
                         [log] generate the SQL for report query!
    
    
                   check_sql:
                         [log] The SQL is good, so next action is gather_data!
    
    
                   gather_data:
                        [log] gather the data for report, its next action is format_report!
     .
                   format_report:
                         [log] format report!
    
    
                   done:
                         [log] Done!
    
    
    

    We could get some feels about the RDL element types from the sample above. There are five RDL element types inside this RDL snippet that are report, reportaction, variable, if, and log, every element type has respective attributes and functionality, such as reportaction and if are mainly used for controlling the procedural flow, variable is used for specifying the new macro variables and assigning the value to existed variables, log is used for writing the log

  • Aspose.Report - The brief introduction to RDL element class and interface model

    I am currently working on RDL element class and interface model, here is the brief introduction.

    •   BaseElement - Base abstract RDL element class

    The BaseElement class is an abstract class for all of RDL elements; it provides three major functionality – Composite structure support, Serialize support, logging and debugging support.

    1. Composite structure support – considering the RDL is based on XML document, so every element is capable to hold the reference of its child elements. It also provides an interface to ensure other visitor classes to navigate entire or parts of RDL elements inside a report
    2. Serialize support – it is useful to be able to serialize the RDL elements to a XML based file so that we create a custom RDL file for a report
    3. Logging and debugging support - every RDL element includes a location object that is used to record a position by which we can locate any RDL element inside the RDL file, a location object includes line number and column number so that the report engine could print the user friendly error message when a RDL file exists problem.

     

    • The RDL element interface based on Inversion Of Control (IOC) pattern and prototype pattern.

    Considering the extensibility nature of RDL elements, we adopt the Inversion Of Control pattern  to apply the extensibility to all of RDL elements..

    1. A RDL element might be a report item such as a report header, or a macro variable type such as directory or connection string. We group those different RDL elements according to their common functionality by different RDL element interfaces such as ReportItem or VariableType, every interface includes a set of common virtual methods and properties so that the report engine only needs to deal with a few RDL element interfaces without knowing various specific RDL element classes. For instance, if we need to draw a box on report, we could write a new descendant BaseElement class ReportBox implemented the ReportItem interface that includes Positon propertiy and Draw method, then compile this class into a centralized or separated DotNet assembly and copy it to a specified folder. When report engine read this box definition from a RDL file, it would go to this folder to scan all of RDL assemblies, locate the ReportBox class and initialize it through reflection. 
    2. As we know that scanning of Dotnet assemblies and reflection are sort of expensive, so we adopt the Prototype pattern in order to minimize the number of scanning and reflection. Report engine only scan the RDL assemblies and initialize the instance of a specific RDL element class once while report engine encounter its definition at the first time, then we add this instance into a in-memory collection, so that report engine could create other same element class instances by looking up this collection and making copies of existed RDL element instance, modifying them as appropriate properties.
  • Aspose.Report - The module list for report tools

    The following is the module list for upcoming report tools, the first release will include report build engine, visual report designer and data gather interface.

    • Report build engine.

    The Report build engine could create and format a report based on a RDL (report definition language) script, RDL is an industry standard and a kind of extensible script, the different development tools vendor could add their own predefined syntax into it. Here is the brief introduction about which feature our RDL script will support.

    1. The definition of general report layout - such as the height of report header, the count of report column, etc.
    2. The definition of report data source - such as a SQL for retrieving data from database or a Tab delimited text file, the Report build engine will retrieve the data based on SQL by invoking the data gather interface.
    3. The definition of some simple procedural flow logic - such as loop and branch (if/else) by which the user could customize some complex reports that can be varied according to some specific situation at the reports building stage.
    4. The definition of some macro variables - It has two purposes, one is that it can work with the definition of procedural flow logic to handle the complex reports; another is that its value could be replaced with some text contents at the reports building stage.
    5. The definition of security validation - It is used to verify if the contents inside the reports can be retrieved and viewed by specified users or groups, the contents could be entire report body, or some report columns, or some report cells only. The Report build engine will validate the security by invoking the report security interface when it encounters the definition of security validation.
    6. The definition of report output type - it is used to specify which reports output format the report build engine will generate, such as Excel, Word or PDF.
    • Visual report designer

    The visual report designer is a GUI tools that allow the report analysts or developers to design and define the report template by drag and drop visually. It includes the report design GUI and preview GUI, the report template will be save as RDL script for Report build engine using.

    •  Data gather interface

    The data gather interface is based on ADO.NET, it can retrieve the data from various database according the connection string and SQL script, and store the data into local disk for the Report build engine use.

    • Report security interface

    The report security interface includes a set of APIs that are used to verify if specific users or groups have rights to retrieve and view the data. The report security interface provides the support of development extension, so the client could integrate it with their existing authorization system.

    • Visual query builder

    The visual query builder is provided for building the queries visually. It allows users to create and edit queries without knowledge of SQL, prepare and execute queries, and view the results of the execution. It will be integrated with visual report designer.

    • Domain object interface

    The domain object interface is provided for simplifying and speeding up the reports designing process, and minimizing the development effort.

    The domain object interface includes some APIs to import and reference the domain objects marshaled by the predefined web service; the property of these domain objects will be referenced as the definition of macro variables inside the RDL script.

    The domain object interface also includes a visual GUI integrated with visual report designer.

    The users will benefit from this feature by separating the work between the report analysts and backend developers, it means that backend developers can boil down complex server-side database behaviors into simple and easy-to-use business elements that report analysts can easily incorporate into their reports with the visual report design tools. For instance, a cross-tab report need some rows of products in the table as the report header, and the products name and count is varied by different situation, the developers could write a web service to retrieve these product list by passing some parameter, then report analysts could use the visual GUI to reference this web service and specify the parameter as macro variables. The report build engine will invoke this web service to get the product list at the reports building stage. This products web service can be reused by other reports.