ArticleDirectory
Overview
In enterprises, there are more or less reports to show business results. There are many ways to implement reports. The simplest method is to directly display reports in paper. This method does not require the support of any IT system and is easy to use. However, this method is generally only applicable to small enterprises, if the enterprise is a little larger and the data size increases, this method will not be able to cope with the problem. As the usage continues to deepen, the chance of errors will also increase. To solve this problem, enterprises usually mount some IT systems, such as financial systems and ERP systems. These systems have built-in standard reports, of course, there are also many enterprises that use internal development to operate. What I want to talk about here is for these self-developed small systems.
There are multiple technical options for implementing reports, such as Crystal Reports, Microsoft's Report Server, and the Java platform. There are also many free report tools. To achieve a more flexible structure, the reports are generally deployed in the B/S structure. Managers and even bosses can directly view some required reports by simply opening a browser. This method is very flexible, but when the report is large, it may cause serious performance problems. If you submit a report for a long time, it may cause request interruption, or too many dead processes are generated in the background. For example, it may take three hours to complete the report operation. If IE times out or the browser is accidentally closed during the three hours, the results of the report will be nowhere to be searched, however, in fact, the background still occupies a large amount of resources and bandwidth, which is a big blow to the application system. Repeated submissions may even result in data inconsistency. Therefore, this document must provide a better solution to this problem.
In fact, the most ideal way to submit large-capacity reports is to submit a command in the browser, and then hand it over to the backend computing, and then hand it over to the customer for download after the computation, in this way, you don't have to worry about all the adverse effects caused by accidental disconnection of the browser.
Design
This method is used in Oracle EBS. It has a "concurrency manager" in its system that is responsible for receiving requests from customers. It has powerful functions, requests are divided into many types. Reports are only one of them. We can also do a lot of things. Our design is relatively simple, just to implement large-capacity reports, therefore, the design is simpler than it.
The concurrency manager is a SchedulingProgramFirst, it receives the requests submitted by the client, makes a corresponding record in the database, and then continuously polls and checks the status of all requests. If a new request is found, the corresponding program is called to implement this request, that is, the report program is called to generate a report.
How does the client obtain the report generated in the background? The browser is closed. You don't have to worry about this. After a report is generated in the background, the client can download the report in the directory of the corresponding web server.
To store data, you need to create a table named zr_request. The table includes the following fields:
Field name |
Type |
PK/FK |
Description |
Request_id |
Number |
PK |
Auto-increment ID |
Status |
Number |
|
Request status |
Start_time |
Date |
|
Start Time |
End_time |
Date |
|
End Time |
Note: The above fields are only required. You can add other auxiliary or enhanced fields as needed.
On the web server, you need to create two subdirectories
Ø output
Store the generated report file. The report file name is the same as the request ID, so that you can easily find the required report file based on the Request ID.
Ø log
Stores the log files generated during the report generation process. The log files are generated no matter whether the report is correctly executed or not for your selection.
The report file can be downloaded only after it is generated. However, the log file can be viewed at any time as the report file is generated.
Log files can be stored in a TXT-type flat file.
The following describes how to use a program to implement the above design process.
Implementation
The system is implemented using C #, and the database is developed using Oracle and the concurrency manager as a background service. This ensures that the server takes effect immediately after it is started and does not need to be logged on to the server.
The establishment of the concurrency manager is very simple. Use the wizard function of vs2008 to create a background service program, and then slightly modify the program.CodeAs follows:
Private void writelog (string content)
{
Streamwriter writer = new streamwriter (logfile, true );
Writer. writeline (content );
Writer. Close ();
}
Private void start ()
{
Writelog ("concurrent manager startup:" + system. datetime. Now. tostring ());
Tmrdaemon. Enabled = true;
}
/// <Summary>
/// Set specific operations so that the service can perform its work.
/// </Summary>
Protected override void onstart (string [] ARGs)
{
// Todo: Add code here to start the service.
Start ();
}
/// <Summary>
/// Stop the service.
/// </Summary>
Protected override void onstop ()
{
// Todo: Add code here to stop the service.
Writelog ("concurrent manager end:" + system. datetime. Now. tostring ());
}
Private void tmrdaemon_elapsed (Object sender, system. Timers. elapsedeventargs E)
{
Try
{
String SQL = "select * from (select request_id from zr_request t where status = 0 order by creation_time) Where rownum <2 ";
Dataaccessor DATA = new dataaccessor ();
String result = data. executescalar (SQL );
If (result! = "")
{
Writelog ("start to call the request program, requestid:" + Result + "" + system. datetime. Now. tostring ());
Process. Start (application. startuppath + "\ zrrequest.exe", result );
Writelog ("the end of the call request, requestid:" + Result + "" + system. datetime. Now. tostring ());
}
}
Catch (exception ex)
{
Writelog ("An error occurred while calling the request program because:" + ex. Message + "" + system. datetime. Now. tostring ());
}
}
A timer is used in the above Code. This control can be added on the design interface and set a time interval, for example, 1 minute. This time is the polling time of the concurrency manager and can be grasped by yourself.
In the program code of the program, you can also see that the generated report is a program called zrrequest.exe. This is the main program of the system, which is mainly responsible for generating reports. In this program, the report generation method is the same as the conventional method. You only need to store the generated files in the specified directory. After the report is generated, notify the database tag to make a change. The main code snippets are as follows:
Private Static void genreportout (string reportid, string reportfilename, string outfilename, string argumenttext, string outputtype)
{
Dataaccessor DATA = new dataaccessor ();
ReportDocument document = new reportdocument ();
Document. Load (reportfilename );
String SQL = "select SQL, table_name from zr_report_sqls t"
+ "Where deleted = 0 and status = 1 and REPORT_ID =" + reportid;
Datatable table = data. executereader (SQL). Tables [0];
Foreach (datarow row in table. Rows)
{
String tablename = row ["table_name"]. tostring ();
SQL = row ["SQL"]. tostring ();
SQL = replacesqlparametervalue (SQL, argumenttext );
Datatable tablereport = data. executereader (SQL). Tables [0];
Document. database. Tables [tablename]. setdatasource (tablereport );
}
Exportoptions crexportoptions = new exportoptions ();
Diskfiledestinationoptions crdiskfiledestinationoptions = new diskfiledestinationoptions ();
Crdiskfiledestinationoptions. diskfilename = outfilename;
Crexportoptions = Document. exportoptions;
Crexportoptions. destinationoptions = crdiskfiledestinationoptions;
Crexportoptions. exportdestinationtype = exportdestinationtype. diskfile;
Crexportoptions. exportformattype = getexportformattype (outputtype); document. Export ();
Document. Close ();
}
In the above functions, the report generation and storage are realized. Of course, this function is only the core part of the processing process. It must be called by the shell program. It is limited by space. Here, you can describe the program code as needed.
Summary
The above programs are only backend programs on the server. To download Real reports, you must develop several B/S pages to support them. This part is relatively simple, it is also relatively independent from the background services and is not described too much.
The above is only a description of the implementation idea, excluding all the code. If you are interested, you can refer to your own development and add your own ideas. This is the biggest achievement.