No announcement yet.


This is a sticky topic.
  • Filter
  • Time
  • Show
Clear All
new posts

  • JasperStarter

    After reading the forum post about PHPJasperXML, I did some serious research into the many ways that reports can be managed from ScriptCase. I tried dozens of methods before stumbling across the jasperstarter project on SourceForge.

    PHPJasperXML is very limited, and it's extremely easy to break a report with no way to debug the problem. And it's slooooooooow.

    JasperStarter/ is built around the latest (5.6.0 as of this post) Jasper Server reporting engine. It supports every feature of the free iReports / JasperStudio report design tools, provides output in any format that you might want, and doesn't beat your server to death every time a report is run.

    From ScriptCase, I build a JasperStarter command line in a variable after prompting the user for constraints, make that variable global, then I redirect to a tiny bit of PHP that executes the command line built from ScriptCase. When the report is done, that php outputs a download link, or emails the report, or displays it to the screen, depending on the constraints provided by the user.

    I'll try to put together a tutorial on a complete reporting system when things slow down here, but many of you will be able to use this project right away.

    I haven't tried it on Windows because that's ... amateur. The project site claims that it works there however, so feel free to shoot yourself in the foot. Use Access for a database while you're at it.

    On CentOS 6, I installed a real Java VM, 1.8, instead of OpenJDK 1.5, and wrote a frontend bash script to manage report parameter parsing. I'll share that script in the tutorial, and explain how it eases management of scheduled/automatic reporting.

    Be aware that the JasperStarter install directory has a folder named jdbc. THAT is where you drop your JDBC connector for MySQL, PostgreSQL, Snoracle, MSSQL, etc. You would have dropped it in the wrong place, trust me.

    I hope this is already helpful, and I expect it will become

  • #2
    looks really good.

    do you have any idea how to generate thousand bills and email them with your method ?


    • #3
      Waiting for your next post.
      S. M. Rajibul Huda
      CEO & Founder


      • #4
        do you have any idea how to generate thousand bills and email them with your method ?
        That is technically infeasible, Mr. Spambotbuilderguy!


        • #5
          Originally posted by Giblet535 View Post
          That is technically infeasible, Mr. Spambotbuilderguy!
          it's not for spamming. Forget sending email.

          i need something for creation billing pdf like what telecommunication operator do.
          maybe just generate and store them locally, and print them later.


          • #6
            I'm pretty sure that there's an invoice template that installs with the free iReport or Jasper Studio (iReport, spelled differently) tools. Once the report (and its parameters) are defined and saved, you can run it from PHP with an exec_shell() call.

            JasperStarter simply gives you the flexibility of Jasper Reports Server from a command-line without the Tomcat headaches and the bloat of Jasper Server's Tomcat web interface. The cost is that you must manage parameter handling, scheduling, etc. from your application.

            A JasperServer box needs 8GB of RAM and probably needs to be dedicated. Java and Windows share several attributes.
            A JasperStarter (Linux) box works great with 1GB of RAM and can still run Apache web application services, MySQL/PostgreSQL, a V7 ScriptCase dev environment, a ScriptCase v8 dev environment, and still sit idle most of the time.

            Email can be handled via sendmail, of course, just like any Linux system can do out of the box.


            • #7
              Thanks Giblet535. it's really helpful.
              I'm gonna try all this.


              • #8
                Hi Giblet535

                Works great in Windows but in Linux i have some trouble.
                Same report ( .jasper or .jrxml ), same command line but ends with an error "Error filling report Error executing SQL statement for : <report_name>"

                The command line:

                ./bin/jasperstarter pr -fpdf <report_name>.jrxml -tgeneric -usa -p<password> -n<DBNAME> --db-driver --db-url jdbc:sqlserver://

                Any hint on this?
                Giorgio Bravi
                Dolphin Software & Thinkware


                • #9

                  the command line should be

                  ./bin/jasperstarter pr -fpdf <report_name>.jrxml -tgeneric -usa -p<password> --db-driver --db-url jdbc:sqlserver://<dbserver>;databaseName=<dbname>

                  works like a charm!! Thanks Giblet535 for this.
                  Giorgio Bravi
                  Dolphin Software & Thinkware


                  • #10
                    Jasperstarter Type Command

                    Hi gbravi and Giblet535, would you sharing to us how to type command from scriptcase ?

                    Originally posted by gbravi View Post

                    the command line should be

                    ./bin/jasperstarter pr -fpdf <report_name>.jrxml -tgeneric -usa -p<password> --db-driver --db-url jdbc:sqlserver://<dbserver>;databaseName=<dbname>

                    works like a charm!! Thanks Giblet535 for this.


                    • #11
                      Hi suyonob

                      you can execute any shell command from php using the exec() command.

                      Hope this help
                      Giorgio Bravi
                      Dolphin Software & Thinkware


                      • #12
                        Getting started

                        My apologies for the delay. Life is busy sometimes.

                        All of this stuff is free, but if you're not familiar with Java, XML, or Jasper Reports, you will benefit greatly from buying a JasperSoft support contract.

                        No, I will not support Jasper or Java for you. Go ask Google.

                        Note that I use MySQL under CentOS, but this should work for any SQL engine on any OS. JasperStarter runs on every OS that has a Java 7 or 8 build. I haven't tried it against OpenJDK, but that will probably work also.

                        These instructions assume you're installing on Linux. Windows installation of the pieces will be different, slower, and it will break on the first Tuesday of every month. I boot into Windows when I need to program a Windows application or play a Windows-only 3D game, but make no mistake: I hate Windows. It's low-tech trash that should have died with its much better predecessor, VMS. Don't even think of asking me a Windows-related question.

                        Here are the pieces that make this work. I will not explain how to install, use, or update these products. That has already been done on the respective web sites. I will provide some information on how to integrate these with ScriptCase, and I will provide some simple scripts to make it easy to give your clients what they can use.

                        • Java - the language that drives the report designer (iReports or JasperSoft Studio), and drives JasperStarter
                        • iReports (or JasperSoft Studio) - the excellent report design GUI
                        • JasperStarter - a backend driver for reports that turns your report into PDF, .DOC, .XLS, ectc.

                        First, get Java if you don't already have it. Yes, Java is only good for prototyping, but it's also very good for reporting. You need at least the runtime. I would prefer to use Java 8 for security reasons, but iReport has trouble with it. So let's install JDK 7 with the updates. Get that here.

                        The next thing you'll need is a Jasper report to run. I use the older iReports 5.5.0 GUI to design reports. The lastest Jasper Studio works fine, but iReports used more sensible terms, and the layout is better arranged for rapid report generation. I haven't tried the 5.6.0 iReports yet.

                        You can get these from JasperSoft or you can get them over on SourceForge.

                        iReport 5.6.0 can be obtained here.

                        Jasper Studio 6.0.1 can be obtained here.

                        iReports and JasperSoft Studio use an installer script that will create desktop icons. I used the defaults for answering, and I installed on Ubuntu.

                        Install, then start iReports. Use the wizard to set up a development connection to your own test database. Use the report wizard to design a very simple report using one of the provided report templates.

                        Go for simple at first! Create a few simple reports and click Preview to see the output. Sweet!

                        Jasper is an extremely powerful reporting system, and it's not difficult to learn, but it is not always obvious how the pieces tie together. JasperSoft has an excellent open forum, and there are many online videos, tutorials and, did I mention, there's a report wizard.

                        Now, you'll need JasperStarter. JasperStarter does, from a PHP script, from an SC event, or even an unattended scheduled job, what the Preview does within iReports. In short, it will run a report with parameters and dump the PDF/DOC/XLS/HTML where you tell it to. Get it here. I installed JasperStarter at /opt/jasperstarter, then I adjusted the default PATH environment variable to add /opt/jasperstarter/bin to the search path in /etc/profile. JasperStarter provides all of the libraries that it needs in jasperstarter/lib. If you intend to move these libraries around, you might discover that JasperStarter no longer does what you want it to do.

                        No, I haven't set this up on Windows. I have never tried to fuel my Ducati motorcycle with bacon grease, either. Either of those is possible, but failure is the only guaranteed outcome. Even Grandma can use Windows. Let her.

                        All of the above products are documented at or near the links above.

                        You now have everything needed to design/run professional quality reports in a matter of minutes.

                        Play with iReports. Take a look at the Parameters section. We'll be adding Parameters in the following posts. Also take a look at how easy it is to take a poorly-formatted SQL field and display it any. way. you. want.

                        OK, we covered some very important things in this first part:
                        • I don't like Windows, which noobs think is "new" but is really based on a much better OS, VMS, which went extinct before the dinosaurs. Noobs. Go figure.
                        • Java is like an evil little monkey, but it's an evil monkey that does some clever things if strong coffee is involved. That's why it's called "Java".
                        • How to obtain the parts for a DIY, enterprise-class, reporting system that works very well with ScriptCase.

                        The next posts will address adding a ScriptCase Control Application that allows any everyday user to select and run your reports, even if you wrote the reports to use complex constraints that a user wouldn't understand.

                        I will also provide a helper script that makes completely automated emailed reports as easy as listing the records in a database.

                        Last edited by Giblet535; 02-02-2015, 01:44 PM.


                        • #13
                          Pat 2

                          Part 2 assumes that you have already installed Java, iReports, and Jasperstarter, and it assumes that you have created a very simple report.

                          Part 2 examines ONE way to set up easy-to-use reporting for your users.

                          You have the tools and you're learning to use them. Now, you need to think through how your users will need to run reports. That seems simple, but it seldom is. As with any User Interface (UI), I find it best to target the least-technical user. That user's skills are limited to 2) "I can read the comic section of a newspaper, most of the time.", and "Cat pictures! W00t!11!!"

                          Insulting users is one of the few joys that a good programmer is allowed to (secretly) enjoy. So, don't judge.

                          Outline your requirements.

                          We will need at least two interfaces: admin and user.

                          The admin will set up which reports are visible to the user, and provide some useful information about each report.

                          I wanted to allow my admin users to define reports from within a ScriptCase control app with:
                          • A freeform user friendly name. (unique key)
                          • The location of the report file. (Upload/download enabled)
                          • The location of the PHP script that starts the report. (Upload/download enabled)
                          • A description of what the report does and what it is for.
                          • A "preview" screenshot with an actual screen grab of what this report outputs. (Upload/download enabled)
                          • Since JasperStarter throws an error if you specify Parameters that are not included in the Jasper report, the user interface should only prompt for those parameters (START_DATE, END_DATE, EMPLOYEE, etc) that are required for the selected report to run.
                          • The SQL used to create the report.

                          A table that can drive this, T_Reports_List:

                          | Field              | Type          | Null | Key | Default | Extra          |
                          | _id                | int(11)       | NO   | PRI | NULL    | auto_increment |
                          | Report_Name        | varchar(255)  | YES  | MUL | NULL    |                |  // A friendly name
                          | Report_XML_URL     | varchar(255)  | YES  |     | NULL    |                |  // The relative path to the .jrxml report
                          | Report_Script_Path | varchar(255)  | YES  |     | NULL    |                | // The path to the StartTheReport PHP script
                          | Report_Desc        | text          | YES  |     | NULL    |                | // A friendly description of what the report does
                          | Report_Preview     | varchar(255)  | YES  |     | NULL    |                | // Relative path to screenshot
                          | Parameters_Mask    | mediumint(9)  | YES  |     | NULL    |                | // Bitmask (see below)
                          | Report_SQL         | varchar(4096) | YES  |     | NULL    |                | // A place to hold the SQL that drives this
                          The only thing that's weird here is Parameter_Mask.

                          Parameters_Mask is used as a bitmap field. It can be used with a ScriptCase multi-select binary field, and allows a reports admin type to specify which report constraints their report requires, and/or whether a report is visible to end users.

                          Bitmaps use one bit for each meaning. Their values are usually described in hexadecimal because using hexadecimal shows the world that you have Mad SkillZ.

                          0x0001 (hex) = 0000 0000 0000 0001 (binary)
                          0x0002 (hex) = 0000 0000 0000 0010 (binary)
                          0x0100 (hex) = 0000 0001 0000 0000 (binary)

                          ScriptCase Select fields, with multi-select (binary) and dropdown with checkboxes, allow you to quickly define a set of bits with a checkbox for each. The list of defined values are increasing-order bits, LSB at the top.

                          For example purposes only (tailor this to your own needs), we will assume that the bitmask has the following value-based meanings:
                          0x0001 = START_DATE is required
                          0x0002 = END_DATE is required
                          0x0004 = EMPLOYEE is required
                          0x0008 = DEPARTMENT is required
                          0x0010 = COUNTRY is required
                          0x0100 = Not Visible By End Users

                          A Parameter_Mask of 0x103 (0001 0011 binary) means this is a report that requires Start Date and End Date parameter values, and is NOT visible to end users.

                          Go ahead and add Parameters to your simple report (right-click Parameters in the left pane of iReport, select Add Parameter, then edit its properties in the right pane). For example, START_DATE and END_DATE that are Java Strings, then we add these to your report's SQL as a WHERE clause. For example:
                          SELECT SUM(total) AS Total FROM SALES WHERE sale_date >= $P{START_DATE} AND sale_date <= $P{END_DATE}
                          Parameters must be added after the Report Wizard is done. They can be used anywhere in the report via $P{PARAMETER_NAME}.

                          Creating the ScriptCase application to drive this table is reasonably easy:
                          • Auto-create the grid and form apps for your table
                          • Edit the form app, set the Report_Name as the unique key, then expand the Fields list
                          • Report_XML and Report_Script_Path will be type "Document (File Name)". I specified that the "Subfolder" should be "/reports", and that the acceptable filetypes for Report_XML would be "JRXML;jrxml;JASPER;jasper"
                          • Report_Preview will be type "Image (File Name)", with file type "PNG;png"
                          • Parameters_Mask will be type "Select", Manual lookup, Multiple Values (binary), with defined values "Start Date", "End Date", and "Employee",and we''l select "Use dropdown with checkboxes"

                          Note: .jrxml is the output of iReports or JasperSoft Studio. The report must be compiled (.jasper filename) before it will run, but JasperStarter is smart enough to do this for us. You can upload only the compiled form if you like. I upload the .jrxml because I like to have the "source code" for the report available.

                          Now you can generate/run this form and upload that report you created. We'll use that report in part 3, when we set up the end user control app that runs the report.

                          We learned that I judge people then warn people not to judge me. I learned this in church. Then we set up a basic reports-list table and created the grid and form to populate that table with values.

                          In Part 3, we'll set up the end-user ScriptCase Control application that allows the user to see what a report does, provide needed parameters for that report, then display that report in PDF on their screen.

                          Last edited by Giblet535; 02-03-2015, 11:10 AM.


                          • #14
                            Part 3

                            In Part 2, we made fun of end users. End users are perhaps the funniest little clowns of the entire plant kingdom, and that is why they are as revered and respected as they are. We also created a basic reports list table, added a grid to list the reports, and added a form to add/modify/delete reports.

                            Now we'll create a ScriptCase Control Application that allows its user to select a report from a dropdown, then displays the details of that report, and prompts the user for the required parameters.

                            But first, back to our Outline.

                            The User Interface should allow the user to:
                            • Select only the User-Viewable reports.
                            • See the Report Name (output only)
                            • See the Report Description (output only)
                            • See the Report Preview screenshot (output only)
                            • Enter report parameters (these can be anything, dates, names, etc)

                            That isn't pretty, but it's easy to use, intuitive, and it's better than what you have now.

                            So, begin by creating an empty Control Application, and set up the layout however you like. Expand the empty Fields list, and add a "Select" field named Report_ID, use "Automatic" lookup, use a blank Title, and select refresh when selection changes. The following SQL is probably adequate if a Parameters_Mask of 0x100 means Admins-Only:
                            SELECT _id, Report_Name 
                            FROM T_Reports_List
                            WHERE (Parameters_Mask & 0x100) = '0' 
                            ORDER BY Report_Name
                            Add a Text type field named Description.
                            Add an Image (file name) field named Preview, and wonder why there isn't just an "Image Display" field type.
                            Add a Date field named Start_Date and provide a popup calendar.
                            Add a Date field named End_Date and provide a popup calendar.
                            Add a Text field named Employee.
                            Add a Select field named Output, with Manual Lookup, and provide the following report output types:
                            Adobe PDF with value "pdf"
                            Microsoft Excel with value "xls"
                            Now click Toolbar settings and change the OK button label to "Run".

                            We want to hide report parameters unless a report uses them. So let's expand the Events. Click the onScriptInit event, and enter:
                            sc_field_display({Start_Date}, off);
                            sc_field_display({End_Date}, off);
                            sc_field_display({Employee}, off);
                            When a user selects a report, we have opted to refresh the screen and we can use that to enable or disable the display of report parameters, so click on the onRefresh event and plug in the code:
                            sc_lookup(rs, "SELECT Parameters_Mask,Report_XML_URL,Report_Script_Path,Report_SQL,Report_Preview FROM T_Reports_List WHERE _id = '".{Report_ID}."'");
                            if( count({rs}) != 0 ) {
                            	$mask = {rs[0][0]};
                            	if( ($mask & 0x01) == 0x01 ) {
                            		sc_field_display({Start_Date}, on);
                            	} else {
                            		sc_field_display({Start_Date}, off);
                            	if( ($mask & 0x02) == 0x02 ) {
                            		sc_field_display({End_Date}, on);
                            	} else {
                            		sc_field_display({End_Date}, off);
                            	if( ($mask & 0x08) == 0x08 ) {
                            		sc_field_display({Employee}, on);
                            	} else {
                            		sc_field_display({Employee}, off);
                            	$xml_file = "/var/www/html/file/doc/reports/".{rs[0][1]};
                            	{Preview} = {rs[0][4]};
                            	$report_php = {rs[0][2]};
                            Finally, we want to run the report and we'll do that from the onValidate event which is fired by the user clicking the app's "OK" button which we labelled "Run". Click the onValidate event and enter the following code:
                            $OUTPUT = {Output};
                            $cmd = "/opt/jasperstarter/bin/jreport ";
                            $db_name = "MyDatabaseName";
                            $cmd .= " -t ".$OUTPUT." -j \"".[xml_file]."\" -d ".$db_name;
                            sc_lookup(rs, "SELECT Parameters_Mask FROM T_Reports_List WHERE _id = '".{Report_ID}."'");
                            if( count({rs}) != 0 ) {
                            	$mask = {rs[0][0]};
                            	if( ($mask & 0x01) == 0x01 ) {
                            		$cmd .= " -S ".$START_DATE;
                            	if( ($mask & 0x02) == 0x02 ) {
                            		$cmd .= " -E ".$END_DATE;
                            	if( ($mask & 0x08) == 0x08 ) {
                            		$cmd .= " -T \"".$EMPLOYEE."\"";
                            sc_redir([report_php], "_blank");
                            You probably guessed that the onValidate event is building a command line based on the defined report's Parameters_Mask field values. Obviously, you would want to add some sanity checks on the user input. This is just a simple example.

                            We'll be calling a shell script, "jreport", that you don't have yet. That script will be provided in Part 4, because some explanation about why it is even needed is helpful, and because it adds the ability to email reports.

                            Now, click Application->Global Variables. Set the displayed global variables to "Out".

                            For the moment, we should pause and test what we have so far. But we need that script that drives our report.

                            Edit your file pointed-to by Report_Script_Path, and enter the following PHP code:
                            $cmd = $_SESSION['cmd'];
                            //$output = shell_exec($cmd);
                            echo $cmd;
                            There may be some debugging needed, but this is really simple. If I left something out, let me know and I'll correct it. Otherwise, it's probably just a typo, so search for typing errors and you'll learn more.

                            We now have an application to upload and define a Jasper report, and an application to run a report which prompts us for only the parameters that the selected report accepts (and requires!). When we run the user application, it displays a command line with the correct Jasper report file name, the correct output format, and all of the parameter values. String values are properly quoted.

                            Part 4 will include and cover the jreport shell script, we'll discuss the above onValidate event some more, and explain how the above control application behaves within the scope of a ScriptCase Menu Application.

                            Last edited by Giblet535; 02-03-2015, 11:15 AM.


                            • #15
                              Part 4

                              In Part 3, we put a simple user report app together and tested it. We [B]did[B] test it, right? Good.

                              That app calls a shell script named "jreport":
                              # Edit this stuff or everyone will laugh.
                              export MAILFROM="Kommissar <>"
                              ## Make sure you either have a /opt/Reports/coversheets folder that is owned by your production web server
                              ## or that you have edited all occurrences of that path to point to where you'll keep your cover sheets.
                              ## See below.
                              export CMD="-t mysql -H -u $DB_USER -n $DB -p $DB_PASS"
                              RAWCMD="mysql -u$DB_USER -p$DB_PASS $DB"
                              export MAILTO=""											## Email addrs, space delimited
                              export SUBJECT=""											# Subject
                              export ATT_FILE=""											# file to attach
                              export ATT_AS_FILE=""
                              export MAILPART=`uuidgen`									## Generates Unique ID for body
                              export MAILPART_BODY=`uuidgen`								## Generates Unique ID for attachment
                              help() {
                              	echo "`basename $0` usage: `basename $0` args"
                              	echo " -e EmailAddress (Sends report to EmailAddress)"
                              	echo " -v (Sends report to stdout)"
                              	echo " -d Database (Uses database Database as data source)"
                              	echo " -h (This help documentation)"
                              	echo " -t Type (Output type: pdf, rtf, xls, xlsx, docx, odt, ods, pptx, csv, html, xhtml, xml, or jrprint)"
                              	echo " -f (Download link)"
                              	echo " -j JasperReport (full path to the .jrxml or .jasper report definition)"
                              	echo " -n Title (Title becomes SUBJECT: tag in emails)"
                              	echo " -S StartDate (sets the START_DATE parameter for the JasperReport)"
                              	echo " -E EndDate (sets the END_DATE paramater for JasperReport)"
                              	echo " -T Employee (sets the EMPLOYEE parameter for JasperReport)"
                              export PARAMS="-P"
                              while getopts "he:vd:n:t:fS:E:T:j:" opts ; do
                              	case $opts in
                              			MAILTO=$OPTARG ;;
                              			VIEWDL="view" ;;
                              			DB=$OPTARG ;;
                              			OUTTYPE=$OPTARG ;;
                              			VIEWDL="download" ;;
                              			PARMS="$PARMS \"START_DATE=$OPTARG\"" ;;
                              			PARMS="$PARMS \"END_DATE=$OPTARG\"" ;;
                              			PARMS="$PARMS \"EMPLOYEE=$OPTARG\"" ;;
                              			JASPER=$OPTARG ;;
                              			SUBJECT="Report - $OPTARG " ;;
                              			exit 0 ;;
                              			echo "Invalid argument: $OPTARG "
                              			exit 1 ;;
                              			echo "$OPTARG  requires an argument"
                              			exit 1 ;;
                              if [ -z "$JASPER" ] ; then
                              	echo "No jasper report specified!"
                              	exit 2
                              TMP=`dirname $JASPER`
                              TMP="`dirname $TMP`/tmp"
                              REPFNAME=`basename $JASPER | cut -d. -f1`
                              JBASE=`echo $JASPER | cut -d. -f1`
                              JSUFF=`echo $JASPER | cut -d. -f2`
                              # Create this folder owned by your web server. Add an HTML email body for each of your reports
                              # Keep it simple. 
                              export BODY_FILE="/opt/Reports/coversheets/`basename $JASPER | cut -d. -f1`.html"		# file holding mail body
                              if [ -f "$BODY_FILE" ] ; then
                              if [ -f "$JBASE.jasper" -a "$JBASE.jasper" -nt "$JBASE.jrxml" ] ; then
                              	/opt/jasperstarter/bin/jasperstarter cp $JASPER
                              SCRIPTPATH="$(dirname $0)"
                              echo "$*" >> /opt/Reports/jreport.log
                              # Java command lines go bonkers with a perfectly OK BASH command line, so we'll pipe it to
                              # the basic shell.
                              echo /usr/bin/java -cp "$SCRIPTPATH/../lib" -jar "$SCRIPTPATH/../lib/jasperstarter.jar" \
                                pr "$JASPER" -f $OUTTYPE -o "$TMP/$REPFNAME" -P `echo $PARMS` $CMD | /bin/sh 2>&1
                              # email, view or download?
                              BOUNDARY="Message-Boundary-`date +%s|md5sum`"
                              BOUND="Message-Boundary-`echo $BOUNDARY|md5sum`"
                              BODY_TEXT=`cat $BODY_FILE`
                              if [ "$VIEWDL" = "view" ] ; then
                              	cat $OFILE
                              	#rm -f $OFILE
                              	if ! [ -z "$MAILTO" ] ; then
                               			echo "From: $MAILFROM"
                               			echo "To: $MAILTO"
                               			echo "Subject: $SUBJECT"
                               			echo "MIME-Version: 1.0"
                               			echo "Content-Type: multipart/mixed;"
                               			echo " boundary=\"$BOUNDARY\""
                               			echo ""
                               			echo "This is a MIME formatted message.  If you see this text it means that your"
                               			echo "email software does not support MIME formatted messages."
                               			echo ""
                               			echo "--$BOUNDARY"
                               			echo "Content-Type: text/html; charset=utf-8"
                               			echo "Content-Transfer-Encoding: 7bit"
                               			echo ""
                               			echo "$BODY_TEXT"
                               			echo ""
                               			echo "--$BOUNDARY"
                               			echo "Content-Type: `file -ib $ATT_FILE | cut -d\; -f1`;"
                              			echo " name=\"$(basename $ATT_FILE)\""
                               			echo "Content-Transfer-Encoding: base64"
                               			echo "Content-Disposition: attachment;"
                              			echo " filename=\"$(basename $ATT_FILE)\""
                               			echo ""
                               			uuencode -m $ATT_FILE $(basename $ATT_FILE) | grep -v "begin-base64 644 "
                               			echo "--$BOUNDARY--"
                               			echo ""
                              		) | /usr/sbin/sendmail $MAILTO
                              		rm -f $ATT_FILE $ATT_FILE.uu
                              		if [ -f $OFILE ] ; then
                              			echo -e "<br><br><p style=\"text-align: center;\"><h3>Report finished. Download file here: <a href=\"/file/doc/tmp/`basename $OFILE`\">$REPFNAME</a></h3></p>"
                              			echo -e "<br><br><p style=\"text-align: center;\">The report completed, but there is no output.</p>"
                              find $TMP -maxdepth 1 -mmin +239 -type f -exec rm -f {} \;
                              exit 0
                              Background: Java is easily confused by BASH command lines, and normal escaping of whitespace and special characters won't work with that $PARAMS string. JasperStarter can't send emails either, so this script was just an easy way to handle assembling the squirrely JasperStarter parameters list for you, and adding email as an option for report output.

                              If you add parameters other than START_DATE, END_DATE and EMPLOYEE, edit this file to support those parameters.

                              If you're setting this up on Windows, your best bet is to throw this script out and write a replacement in PHP or a console program in C/C++. Sorry. If you could reason with Windows "developers", you wouldn't need to.

                              Save the script and make it executable by the web server. Copy the command line displayed at the end of Part 3 and paste it into a command line prompt. If you get errors, make sure your JasperStarter is where that script thinks it is.

                              Now, let's fix that PHP script from the end of Part 3 to:
                              $cmd = $_SESSION['cmd'];
                              $output = shell_exec($cmd);
                              echo $output;
                              Run your report. A link to the pdf will appear after a few seconds. As you can see, the report looks just like the preview in iReports.

                              It's very easy to expand on this, and it would be great if you posted your successes on one of the forums.

                              I'm sure I made lots of mistakes above, and this will need tweaks for different systems. I was testing/tweaking/testing a threaded C program and typing this from months-old rote between. Call me out on those mistakes. I'll fix 'em.

                              And you Windows zealots: get a sense of humor. I develop for Windows too when the pay is right.