CRJavaHelper

/**
 * This sample code is an example of how to use the Business Objects APIs.
 * Because the sample code is designed for demonstration only, it is 
 * unsupported.  You are free to modify and distribute the sample code as needed.
 * *此示例代码是如何使用业务对象API的示例。
 * *由于示例代码仅用于演示,因此
 * *不受支持。您可以根据需要自由修改和分发示例代码。
 */
package com.businessobjects.samples;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Locale;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;

import com.crystaldecisions.sdk.occa.report.application.DataDefController;
import com.crystaldecisions.sdk.occa.report.application.ReportClientDocument;
import com.crystaldecisions.sdk.occa.report.data.FieldDisplayNameType;
import com.crystaldecisions.sdk.occa.report.data.IConnectionInfo;
import com.crystaldecisions.sdk.occa.report.data.ITable;
import com.crystaldecisions.sdk.occa.report.data.ParameterField;
import com.crystaldecisions.sdk.occa.report.data.ParameterFieldDiscreteValue;
import com.crystaldecisions.sdk.occa.report.data.ParameterFieldRangeValue;
import com.crystaldecisions.sdk.occa.report.data.RangeValueBoundType;
import com.crystaldecisions.sdk.occa.report.data.Tables;
import com.crystaldecisions.sdk.occa.report.data.Values;
import com.crystaldecisions.sdk.occa.report.document.PaperSize;
import com.crystaldecisions.sdk.occa.report.document.PaperSource;
import com.crystaldecisions.sdk.occa.report.document.PrintReportOptions;
import com.crystaldecisions.sdk.occa.report.document.PrinterDuplex;
import com.crystaldecisions.sdk.occa.report.exportoptions.CharacterSeparatedValuesExportFormatOptions;
import com.crystaldecisions.sdk.occa.report.exportoptions.DataOnlyExcelExportFormatOptions;
import com.crystaldecisions.sdk.occa.report.exportoptions.EditableRTFExportFormatOptions;
import com.crystaldecisions.sdk.occa.report.exportoptions.ExportOptions;
import com.crystaldecisions.sdk.occa.report.exportoptions.PDFExportFormatOptions;
import com.crystaldecisions.sdk.occa.report.exportoptions.RTFWordExportFormatOptions;
import com.crystaldecisions.sdk.occa.report.exportoptions.ReportExportFormat;
import com.crystaldecisions.sdk.occa.report.lib.IStrings;
import com.crystaldecisions.sdk.occa.report.lib.PropertyBag;
import com.crystaldecisions.sdk.occa.report.lib.ReportSDKException;
import com.crystaldecisions.sdk.occa.report.lib.ReportSDKExceptionBase;

/**
 * Crystal Reports Java Helper Sample.
 * crystal Reports Java Helper示例。
 * ************************
 * Please note that you need to define a runtime server in order for this class to compile.
 * 请注意,为了编译此类,您需要定义一个运行时服务器。
 * ************************
 * @author Business Objects
 */


/*
* 上面是文字说明,底下是代码实现
* */


public class CRJavaHelper {

    /*
    * datasource: 数据源,它包含连接池和连接池管理两部分。
    * 数据源就是连接到数据库的一条路径,它不存储数据,就是条线路,它记录的是连接的哪条数据库,如何连接。
    * 系统初始化时,将数据库连接对象存储到内存中,当用户需要访问数据库的时候,
    * 并不是去重新建立一个连接,而是去连接池中取出一个已经建立好的空闲连接。
    *
    * */




    /**
     * Logs on to all existing datasource  登录到现有的数据源(连接池和管理连接池)
     * parameter:参数
     * @param clientDoc The reportClientDocument representing (表示) the report being used 正在使用的表
     * @param username    The DB logon user name    数据库登录用户名
     * @param password    The DB logon password     密码
     * @throws ReportSDKException
     */
    public static void logonDataSource(ReportClientDocument clientDoc,  //logonDataSource   登录数据源
                String username, String password) throws ReportSDKException {
        
        System.out.println("CRJavaHelper,logonDataSource,登录到现有的数据源(连接池和管理连接池)");

        clientDoc.getDatabaseController().logon(username, password);    //正在使用的表


    }





    /**
     * Changes the DataSource for each Table   给每个表都要改变数据源(连接池和连接池管理)
     * @param clientDoc The reportClientDocument representing the report being used
     * @param username  The DB logon user name
     * @param password  The DB logon password
     * @param connectionURL  The connection URL
     * (URL: uniform resource locator 统一资源定位符,每一个网页都有自己的名称,是唯一的,就是网页最上面的那个地址)
     * @param driverName    The driver Name     驱动名称
     * @param jndiName        The JNDI name     JNDI名称
     *(JNDI: java naming and directory interface java命名和目录接口)
     * @throws ReportSDKException
     */
    public static void changeDataSource(ReportClientDocument clientDoc,
                String username, String password, String connectionURL,
                String driverName,String jndiName) throws ReportSDKException {
        
        System.out.println("CRJavaHelper,changeDataSource,给每个表都要更改数据源(连接池和管理连接池)");

        changeDataSource(clientDoc, null, null, username, password, connectionURL, driverName, jndiName);

    }




    /**
     * Changes the DataSource for a specific Table   给特定的表更改数据源(连接池和连接池管理)
     * @param clientDoc The reportClientDocument representing the report being used
     * @param reportName    "" for main report 主报表, name of subreport for subreport, null for all reports
     * @param tableName        name of table to change. 要更改表的名称   null for all tables. 所有表为 null
     * @param username  The DB logon user name
     * @param password  The DB logon password
     * @param connectionURL  The connection URL
     * @param driverName    The driver Name
     * @param jndiName        The JNDI name  (java naming and directory interface java命名和目录接口)
     * @throws ReportSDKException
     */
    public static void changeDataSource(   //更改数据源
            ReportClientDocument clientDoc, //正在使用的表
                String reportName, String tableName, //主报表 、 要更改的表
                String username, String password, String connectionURL,
                String driverName,String jndiName) throws ReportSDKException {

        System.out.println("CRJavaHelper,changeDataSource,给特定的表更改数据源(连接池和管理连接池),");

        PropertyBag propertyBag = null;
        IConnectionInfo connectionInfo = null;
        ITable origTable = null;
        ITable newTable = null;




        /**
         *Declare variables to hold ConnectionInfo values. 声明用于保存ConnectionInfo值的变量
         *Below is the list of values required to switch to use a JDBC/JNDI   以下是切换到使用JDBC或者JNDI所需值
         * connection 连接
         */

        String TRUSTED_CONNECTION = "false";
        String SERVER_TYPE = "JDBC (JNDI)";
        String USE_JDBC = "true";
        String DATABASE_DLL = "crdb_jdbc.dll";
        String JNDI_DATASOURCE_NAME = jndiName;
        String CONNECTION_URL = connectionURL;
        String DATABASE_CLASS_NAME = driverName;


        /**

         */

        /**
         *  which you may want to uncomment
         *         接下来的几个参数是可选参数,你可能需要取消注释
         *          You may wish to adjust the arguments of the method to pass these values in if necessary
         *          如果有必要,你可能希望调整方法的自变量以去传递这些值
         *
         *          String TABLE_NAME_QUALIFIER = "new_table_name";
         *          String SERVER_NAME = "new_server_name";
         *          String CONNECTION_STRING = "new_connection_string";
         *          String DATABASE_NAME = "new_database_name";
         *          String URI = "new_URI";
         *
         *          Declare variables to hold database User Name and Password values
         *          声明用于保存数据库用户和密码的变量
         */

        String DB_USER_NAME = username;
        String DB_PASSWORD = password;



        // Obtain collection of tables from this database controller 从这个数据库控制器中获取表的集合
        if (reportName == null || reportName.equals("")) {
            Tables tables = clientDoc.getDatabaseController().getDatabase().getTables();
            for(int i = 0;i < tables.size();i++){
                origTable = tables.getTable(i);
                if (tableName == null || origTable.getName().equals(tableName)) {
                    newTable = (ITable)origTable.clone(true);

                    // We set the Fully qualified name to the Table Alias to keep the method generic. 我们将完全限定名称设置为表别名,以保持方法的通用性。
                    // This workflow may not work in all scenarios and should likely be customized to work in the developer's specific situation.此工作流程可能不适用于所有场景,应该根据开发人员的具体情况进行自定义。
                    // The end result of this statement will be to strip the existing table of it's db specific identifiers.该语句的最终结果是从现有表中删除特定于数据库的标识符。
                    // For example Xtreme.dbo.Customer becomes just Customer
                    newTable.setQualifiedName(origTable.getAlias());



                    // Change properties that are different from the original datasource.更改那些与原始数据源不同的属性
                    // For example, if the table name has changed you will be required to change it during this routine table.setQualifiedName(TABLE_NAME_QUALIFIER);
                    //例如,如果表明已更改,则需要在此例程表中更改它。
                    // Change connection information properties.更改连接信息属性
                    connectionInfo = newTable.getConnectionInfo();


                    // Set new table connection property attributes. 设置新表连接属性
                    propertyBag = new PropertyBag();


                    // Overwrite any existing properties with updated values.用更新过后的值来覆盖现有的任何属性
                    propertyBag.put("Trusted_Connection", TRUSTED_CONNECTION);
                    propertyBag.put("Server Type", SERVER_TYPE);
                    propertyBag.put("Use JDBC", USE_JDBC);
                    propertyBag.put("Database DLL",DATABASE_DLL );
                    propertyBag.put("JNDI Datasource Name",JNDI_DATASOURCE_NAME );
                    propertyBag.put("Connection URL", CONNECTION_URL);
                    propertyBag.put("Database Class Name", DATABASE_CLASS_NAME);
                    // propertyBag.put("Server Name", SERVER_NAME); //Optional property
                    // propertyBag.put("Connection String", CONNECTION_STRING); //Optional property
                    // propertyBag.put("Database Name", DATABASE_NAME); //Optional property
                    // propertyBag.put("URI", URI); //Optional property
                    connectionInfo.setAttributes(propertyBag);



                    // Set database username and password 设置数据库名字和密码
                    // NOTE: Even if the username and password properties do not change when switching databases,切记:即使在切换数据库时用户名和密码没有更改,
                    // the database password is *not* saved in the report and must be set at runtime if the database is secured.
                    // 如果数据库是安全的,密码也不能保存在报告中,且必须在运行时设置。
                    connectionInfo.setUserName(DB_USER_NAME);
                    connectionInfo.setPassword(DB_PASSWORD);

                    // Update the table information 更新表的信息
                    clientDoc.getDatabaseController().setTableLocation(origTable, newTable);
                }
            }
        }

        // Next loop through all the subreports and pass in the same information. 接下来循环所有子报表并且传递相同的信息。
        // You may consider creating a separate method which accepts.你可以考虑创建一个单独的的方法来
        if (reportName == null || !(reportName.equals(""))) {
            IStrings subNames = clientDoc.getSubreportController().getSubreportNames();
            for (int subNum=0;subNum<subNames.size();subNum++) {
                Tables tables = clientDoc.getSubreportController().getSubreport(subNames.getString(subNum)).getDatabaseController().getDatabase().getTables();
                for(int i = 0;i < tables.size();i++){
                    origTable = tables.getTable(i);
                    if (tableName == null || origTable.getName().equals(tableName)) {
                        newTable = (ITable)origTable.clone(true);

                        // We set the Fully qualified name to the Table Alias to keep the method generic.
                        // 我们将完全限定名称设置为表别名,以保持方法的通用性。
                        // This workflow may not work in all scenarios and should likely be customized to work in the developer's specific situation.
                        // 此工作流程可能不适用于所有场景,应该根据开发人员的具体情况进行自定义。
                        // The end result of this statement will be to strip the existing table of it's db specific identifiers.
                        //该语句的最终结果是从现有表中删除特定于数据库的标识符。
                        // For example Xtreme.dbo.Customer becomes just Customer.
                        //比如:Xtreme.dbo.Customer 变成了 Customer
                        newTable.setQualifiedName(origTable.getAlias());

                        // Change properties that are different from the original datasource table.
                        //更改与原始数据源表不同的属性。
                        // setQualifiedName(TABLE_NAME_QUALIFIER);

                        // Change connection information properties 更改连接信息属性
                        connectionInfo = newTable.getConnectionInfo();

                        // Set new table connection property attributes 创建新表连接属性
                        propertyBag = new PropertyBag();

                        // Overwrite any existing properties with updated values 用更新过后的数据来覆盖任何现有特征
                        propertyBag.put("Trusted_Connection", TRUSTED_CONNECTION);
                        propertyBag.put("Server Type", SERVER_TYPE);
                        propertyBag.put("Use JDBC", USE_JDBC);
                        propertyBag.put("Database DLL",DATABASE_DLL );
                        propertyBag.put("JNDI Datasource Name",JNDI_DATASOURCE_NAME );
                        propertyBag.put("Connection URL", CONNECTION_URL);
                        propertyBag.put("Database Class Name", DATABASE_CLASS_NAME);
                        // propertyBag.put("Server Name", SERVER_NAME); //Optional property
                        // propertyBag.put("Connection String", CONNECTION_STRING); //Optional property
                        // propertyBag.put("Database Name", DATABASE_NAME); //Optional property
                        // propertyBag.put("URI", URI); //Optional property
                        connectionInfo.setAttributes(propertyBag);


                        // Set database username and password  设置数据库用户名和密码
                        // NOTE: Even if the username and password properties do not change when switching databases,
                        // the database password is *not* saved in the report and must be set at runtime if the database is secured.
                        //切记:即使在切换数据库时用户名和密码没有更改,如果数据库是安全的,密码也不能保存在报告中,且必须在运行时设置。
                        connectionInfo.setUserName(DB_USER_NAME);
                        connectionInfo.setPassword(DB_PASSWORD);

                        // Update the table information 更新表的信息
                        clientDoc.getSubreportController().getSubreport(subNames.getString(subNum)).getDatabaseController().setTableLocation(origTable, newTable);
                    }
                }
            }
        }
    }
    
    /**
     * Passes a populated java.sql.Resultset object to a Table object.将已填充的java.sql.Resultset对象传递给Table对象。
     * 
     * @param clientDoc The reportClientDocument representing the report being used  正在使用
     * @param rs        The java.sql.Resultset used to populate 填充 the Table
     * @param tableAlias    The alias 别名 of the table
     * @param reportName    The name of the subreport 子表.  If tables in the main report 主报告 is to be used, "" should be passed
     * @throws ReportSDKException
     */
    public static void passResultSet(ReportClientDocument clientDoc, java.sql.ResultSet rs,
            String tableAlias, String reportName) throws ReportSDKException {
        System.out.println("passResultSet,Passes a populated java.sql.Resultset object to a Table object.将已填充的java.sql.Resultset对象传递给Table对象。");

        if(reportName.equals(""))
            clientDoc.getDatabaseController().setDataSource(rs, tableAlias,tableAlias);
        else
            clientDoc.getSubreportController().getSubreport(reportName).getDatabaseController().setDataSource(rs, tableAlias,tableAlias);

    }

    /**
     * Passes a populated collection of a Java class to a Table object 将已填充的Java类集合传递给Table对象
     * @param clientDoc     The reportClientDocument representing the report being used
     * @param dataSet        The java.sql.Resultset used to populate the Table
     * @param className        The fully-qualified class name of the POJO objects being passed
     * @param tableAlias        The alias of the table
     * @param reportName    The name of the subreport. 子报表
     *  If tables in the main report is to be used, "" should be passed;如果要使用主报表中的表,应该传递"" ;
     * @throws ReportSDKException
     */
    public static void passPOJO(ReportClientDocument clientDoc, Collection dataSet, 
            String className, String tableAlias, String reportName) throws ReportSDKException,ClassNotFoundException{

        System.out.println("passPOJO, Passes a populated collection of a Java class to a Table object 将已填充的Java类集合传递给Table对象");

        if(reportName.equals(""))
            clientDoc.getDatabaseController().setDataSource(dataSet, Class.forName(className),tableAlias,tableAlias);
        else
            clientDoc.getSubreportController().getSubreport(reportName).getDatabaseController().setDataSource(dataSet, Class.forName(className),tableAlias,tableAlias);

    }

    /**
     * Passes a single discrete parameter value to a report parameter,将单个离散参数值传递给报表参数
     * 
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param reportName    The name of the subreport.  If tables in the main report
     *                         is to be used, "" should be passed
     * @param parameterName    The name of the parameter
     * @param newValue        The new value of the parameter 
     * @throws ReportSDKException
     */
    public static void addDiscreteParameterValue(ReportClientDocument clientDoc, String reportName, String parameterName, Object newValue) throws ReportSDKException{

        System.out.println("addDiscreteParameterValue,Passes a single discrete parameter value to a report parameter,将单个离散参数值传递给报表参数,");

        DataDefController dataDefController = null;
        if(reportName.equals(""))
            dataDefController = clientDoc.getDataDefController();
        else
            dataDefController = clientDoc.getSubreportController().getSubreport(reportName).getDataDefController();

        ParameterFieldDiscreteValue newDiscValue = new ParameterFieldDiscreteValue();
        newDiscValue.setValue(newValue);

        ParameterField paramField = (ParameterField)dataDefController.getDataDefinition().getParameterFields().findField(parameterName, FieldDisplayNameType.fieldName, Locale.getDefault());
        boolean multiValue = paramField.getAllowMultiValue();

        if(multiValue) {
            Values newVals = (Values)paramField.getCurrentValues().clone(true);
            newVals.add(newDiscValue);
            clientDoc.getDataDefController().getParameterFieldController().setCurrentValue(reportName, parameterName ,newVals);
        } else {
            clientDoc.getDataDefController().getParameterFieldController().setCurrentValue(reportName, parameterName , newValue);
        }
    }



    /**
     * Passes multiple discrete parameter values to a report parameter.将多个离散参数值传递给报表参数。
     * 
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param reportName    The name of the subreport.  If tables in the main report
     *                         is to be used, "" should be passed
     * @param parameterName    The name of the parameter
     * @param newValues        An array of new values to get set on the parameter
     * @throws ReportSDKException
     */
    public static void addDiscreteParameterValue(ReportClientDocument clientDoc, String reportName, String parameterName, Object[] newValues) throws ReportSDKException{

        System.out.println("addDiscreteParameterValue,Passes multiple discrete parameter values to a report parameter.将多个离散参数值传递给报表参数。");

        clientDoc.getDataDefController().getParameterFieldController().setCurrentValues(reportName, parameterName ,newValues);
    }




    /**
     * Passes a single range parameter value to a report parameter.  The range is assumed to be inclusive on beginning and end.
     * 将单个范围参数值传递给报表参数。假设该范围包含开始和结束。
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param reportName    The name of the subreport.  If tables in the main report
     *                         is to be used, "" should be passed
     * @param parameterName    The name of the parameter
     * @param beginValue    The value of the beginning of the range
     * @param endValue        The value of the end of the range
     * @throws ReportSDKException
     */
    public static void addRangeParameterValue(ReportClientDocument clientDoc, String reportName, String parameterName, Object beginValue, Object endValue) throws ReportSDKException{

        System.out.println("addRangeParameterValue," +
                "Passes a single range parameter value to a report parameter.  The range is assumed to be inclusive on beginning and end.\n" +
                "将单个范围参数值传递给报表参数。假设该范围包含开始和结束。");

        addRangeParameterValue(clientDoc, reportName, parameterName, beginValue, RangeValueBoundType.inclusive, endValue, RangeValueBoundType.inclusive);
    }




    /**
     * Passes multiple range parameter values to a report parameter.
     *将多个范围参数值传递给报表参数。
     * This overload of the addRangeParameterValue will only work if the parameter is setup to accept multiple values.
     * 只有当参数设置为接受多个值时,addRangeParameterValue的这种重载才会起作用。
     * If the Parameter does not accept multiple values then it is expected that this version of the method will return an error
     * 如果Parameter不接受多个值,则此版本的方法将返回错误。
     *
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param reportName    The name of the subreport.  If tables in the main report
     *                         is to be used, "" should be passed
     * @param parameterName    The name of the parameter
     * @param beginValues    Array of beginning values.  Must be same length as endValues.
     * @param endValues        Array of ending values.  Must be same length as beginValues.
     * @throws ReportSDKException
     */
    public static void addRangeParameterValue(ReportClientDocument clientDoc, String reportName, String parameterName, Object[] beginValues, Object[] endValues) throws ReportSDKException{

        System.out.println("addRangeParameterValue," +
                "Passes multiple range parameter values to a report parameter.\n" +
                "将多个范围参数值传递给报表参数。\n" +
                "This overload of the addRangeParameterValue will only work if the parameter is setup to accept multiple values.\n" +
                "只有当参数设置为接受多个值时,addRangeParameterValue的这种重载才会起作用。\n" +
                "If the Parameter does not accept multiple values then it is expected that this version of the method will return an error\n" +
                "如果Parameter不接受多个值,则此版本的方法将返回错误。");

        addRangeParameterValue(clientDoc, reportName, parameterName, beginValues, RangeValueBoundType.inclusive, endValues, RangeValueBoundType.inclusive);
    }
    
    /**
     * Passes a single range parameter value to a report parameter.
     *将单个范围参数值传递给报表参数。
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param reportName    The name of the subreport.  If tables in the main report
     *                         is to be used, "" should be passed
     * @param parameterName    The name of the parameter
     * @param beginValue    The value of the beginning of the range
     * @param lowerBoundType    The inclusion/exclusion range of the start of range.
     * @param endValue        The value of the end of the range
     * @param upperBoundType    The inclusion/exclusion range of the end of range.
     * @throws ReportSDKException
     */
    public static void addRangeParameterValue(ReportClientDocument clientDoc, String reportName, String parameterName, Object beginValue, RangeValueBoundType lowerBoundType,Object endValue, RangeValueBoundType upperBoundType) throws ReportSDKException{

        System.out.println("addRangeParameterValue," +
                " Passes a single range parameter value to a report parameter.\n" +
                "将单个范围参数值传递给报表参数。");

        DataDefController dataDefController = null;
        if(reportName.equals(""))
            dataDefController = clientDoc.getDataDefController();
        else
            dataDefController = clientDoc.getSubreportController().getSubreport(reportName).getDataDefController();

        ParameterFieldRangeValue newRangeValue = new ParameterFieldRangeValue();
        newRangeValue.setBeginValue(beginValue);
        newRangeValue.setLowerBoundType(lowerBoundType);
        newRangeValue.setEndValue(endValue);
        newRangeValue.setUpperBoundType(upperBoundType);

        ParameterField paramField = (ParameterField)dataDefController.getDataDefinition().getParameterFields().findField(parameterName, FieldDisplayNameType.fieldName, Locale.getDefault());
        boolean multiValue = paramField.getAllowMultiValue();

        if (multiValue) {
            Values newVals = (Values)paramField.getCurrentValues().clone(true);
            newVals.add(newRangeValue);
            clientDoc.getDataDefController().getParameterFieldController().setCurrentValue(reportName, parameterName , newVals);
        } else {
            clientDoc.getDataDefController().getParameterFieldController().setCurrentValue(reportName, parameterName , newRangeValue);
        }
    }

    /**
     * Passes multiple range parameter values to a report parameter.
     *将多个范围参数值传递给报表参数。
     * This overload of the addRangeParameterValue will only work if the parameter is setup to accept multiple values.
     * 只有当参数设置为接受多个值时,addRangeParameterValue的这种重载才会起作用。
     * If the Parameter does not accept multiple values then it is expected that this version of the method will return an error.
     * 如果Parameter不接受多个值,则此版本的方法将返回错误。
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param reportName    The name of the subreport.  If tables in the main report
     *                         is to be used, "" should be passed
     * @param parameterName    The name of the parameter
     * @param beginValues    Array of beginning values.  Must be same length as endValues.
     * @param lowerBoundType    The inclusion/exclusion range of the start of range.
     * @param endValues        Array of ending values.  Must be same length as beginValues.
     * @param upperBoundType    The inclusion/exclusion range of the end of range.
     * 
     * @throws ReportSDKException
     */
    public static void addRangeParameterValue(ReportClientDocument clientDoc, String reportName, String parameterName, Object[] beginValues,RangeValueBoundType lowerBoundType, Object[] endValues, RangeValueBoundType upperBoundType) throws ReportSDKException{

        System.out.println("addRangeParameterValue,Passes multiple range parameter values to a report parameter.\n" +
                "将多个范围参数值传递给报表参数。\n" +
                "This overload of the addRangeParameterValue will only work if the parameter is setup to accept multiple values.\n" +
                "只有当参数设置为接受多个值时,addRangeParameterValue的这种重载才会起作用。\n" +
                "If the Parameter does not accept multiple values then it is expected that this version of the method will return an error.\n" +
                "如果Parameter不接受多个值,则此版本的方法将返回错误。");

        // it is expected that the beginValues array is the same size as the endValues array.预计beginValues数组的大小与endValues数组相同。
        ParameterFieldRangeValue[] newRangeValues = new ParameterFieldRangeValue[beginValues.length];
        for(int i=0;i<beginValues.length;i++){
            newRangeValues[i] = new ParameterFieldRangeValue();
            newRangeValues[i].setBeginValue(beginValues[i]);
            newRangeValues[i].setLowerBoundType(lowerBoundType);
            newRangeValues[i].setEndValue(endValues[i]);
            newRangeValues[i].setUpperBoundType(upperBoundType);
        }
        clientDoc.getDataDefController().getParameterFieldController().setCurrentValues(reportName, parameterName , newRangeValues);

    }
    
    /**
     * Exports a report to PDF.将报告导出为PDF。
     * 
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param response        The HttpServletResponse object
     * @param startPage        Starting page
     * @param endPage        Ending page
     * @param attachment    true to prompts for open or save; false opens the report
     *                         in the specified format after exporting.
     * @throws ReportSDKExceptionBase
     * @throws IOException
     */
    public static void exportPDF(ReportClientDocument clientDoc, HttpServletResponse response, boolean attachment) throws ReportSDKExceptionBase, IOException {

        System.out.println("exportPDF,Exports a report to PDF.将报告导出为PDF。");

        // PDF export allows page range export. PDF导出允许页面范围导出。
        // The following routine ensures that the requested page range is valid.以下例程确保请求的页面范围有效。
        PDFExportFormatOptions  pdfOptions = new PDFExportFormatOptions();
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.PDF);        
        exportOptions.setFormatOptions(pdfOptions);

        export(clientDoc, exportOptions, response, attachment, "application/pdf", "pdf");
    }
    
    /**
     * Exports a report to PDF for a range of pages.将报告导出为一系列页面的PDF。
     * 
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param response        The HttpServletResponse object
     * @param startPage        Starting page
     * @param endPage        Ending page
     * @param attachment    true to prompts for open or save; false opens the report
     *                         in the specified format after exporting.
     * @throws ReportSDKExceptionBase
     * @throws IOException
     */
    public static void exportPDF(ReportClientDocument clientDoc, HttpServletResponse response, ServletContext  context, int startPage, int endPage,boolean attachment) throws ReportSDKExceptionBase, IOException {

        System.out.println("exportPDF,Exports a report to PDF for a range of pages.将报告导出为一系列页面的PDF。");

        // PDF export allows page range export. PDF导出允许页面范围导出。
        // The following routine ensures that the requested page range is valid.以下例程确保请求的页面范围有效。
        PDFExportFormatOptions  pdfOptions = new PDFExportFormatOptions();
        pdfOptions.setStartPageNumber(startPage);
        pdfOptions.setEndPageNumber(endPage);
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.PDF);        
        exportOptions.setFormatOptions(pdfOptions);

        export(clientDoc, exportOptions, response, attachment, "application/pdf", "pdf");

    }
    
    /**
     * Exports a report to RTF.将报告导出到RTF。
     * 
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param response        The HttpServletResponse object
     * @param attachment    true to prompts for open or save; false opens the report
     *                         in the specified format after exporting.
     * @throws ReportSDKExceptionBase
     * @throws IOException
     */
    public static void exportRTF(ReportClientDocument clientDoc, HttpServletResponse response, boolean attachment) throws ReportSDKExceptionBase, IOException {
        // RTF export allows page range export.
        // The following routine ensures that the requested page range is valid
        RTFWordExportFormatOptions  rtfOptions = new RTFWordExportFormatOptions();
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.RTF);        
        exportOptions.setFormatOptions(rtfOptions);

        export(clientDoc, exportOptions, response, attachment, "text/rtf", "rtf");
    }
    
    /**
     * Exports a report to RTF for a range of pages.
     * 
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param response        The HttpServletResponse object
     * @param startPage        Starting page
     * @param endPage        Ending page.  
     * @param attachment    true to prompts for open or save; false opens the report
     *                         in the specified format after exporting.
     * @throws ReportSDKExceptionBase
     * @throws IOException
     */
    public static void exportRTF(ReportClientDocument clientDoc, HttpServletResponse response, ServletContext  context, int startPage, int endPage, boolean attachment) throws ReportSDKExceptionBase, IOException {
        // RTF export allows page range export. The following routine ensures
        // that the requested page range is valid
        RTFWordExportFormatOptions  rtfOptions = new RTFWordExportFormatOptions();
        rtfOptions.setStartPageNumber(startPage);
        rtfOptions.setEndPageNumber(endPage);
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.RTF);        
        exportOptions.setFormatOptions(rtfOptions);

        export(clientDoc, exportOptions, response, attachment, "text/rtf", "rtf");
    }

    /**
     * Exports a report to RTF
     * 
     * @param clientDoc     The reportClientDocument representing the report being used
     * @param response      The HttpServletResponse object
     * @param attachment    true to prompts for open or save; false opens the report
     *                      in the specified format after exporting.
     * @throws ReportSDKExceptionBase
     * @throws IOException
     */
    public static void exportRTFEditable(ReportClientDocument clientDoc, HttpServletResponse response, boolean attachment) throws ReportSDKExceptionBase, IOException {
        // RTF export allows page range export. The following routine ensures
        // that the requested page range is valid
        EditableRTFExportFormatOptions  rtfOptions = new EditableRTFExportFormatOptions();
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.editableRTF);      
        exportOptions.setFormatOptions(rtfOptions);

        export(clientDoc, exportOptions, response, attachment, "text/rtf", "rtf");
    }    
    
    /**
     * Exports a report to RTF for a range of pages.将一系列页面的报告导出为RTF。
     * 
     * @param clientDoc     The reportClientDocument representing the report being used
     * @param response      The HttpServletResponse object
     * @param startPage     Starting page
     * @param endPage       Ending page.  
     * @param attachment    true to prompts for open or save; false opens the report
     *                      in the specified format after exporting.
     * @throws ReportSDKExceptionBase
     * @throws IOException
     */
    public static void exportRTFEditable(ReportClientDocument clientDoc, HttpServletResponse response, ServletContext  context, int startPage, int endPage,boolean attachment) throws ReportSDKExceptionBase, IOException {

        System.out.println("exportRTFEditable,Exports a report to RTF for a range of pages.将一系列页面的报告导出为RTF。");

        // RTF export allows page range export.
        // The following routine ensures that the requested page range is valid
        EditableRTFExportFormatOptions  rtfOptions = new EditableRTFExportFormatOptions();
        rtfOptions.setStartPageNumber(startPage);
        rtfOptions.setEndPageNumber(endPage);
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.editableRTF);      
        exportOptions.setFormatOptions(rtfOptions);

        export(clientDoc, exportOptions, response, attachment, "text/rtf", "rtf");
    }
    
    /**
     * Exports a report to Excel (Data Only).将报表导出到Excel(仅限数据)。
     * 
     * @param clientDoc     The reportClientDocument representing the report being used
     * @param response      The HttpServletResponse object
     * @param attachment    true to prompts for open or save; false opens the report
     *                      in the specified format after exporting.
     * @throws ReportSDKExceptionBase
     * @throws IOException
     */
    public static void exportExcelDataOnly(ReportClientDocument clientDoc, HttpServletResponse response, boolean attachment) throws ReportSDKExceptionBase, IOException {

        System.out.println("exportExcelDataOnly,Exports a report to Excel (Data Only).将报表导出到Excel(仅限数据)。");

        DataOnlyExcelExportFormatOptions excelOptions = new DataOnlyExcelExportFormatOptions();
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.recordToMSExcel);      
        exportOptions.setFormatOptions(excelOptions );

        export(clientDoc, exportOptions, response, attachment, "application/excel", "xls");
    }

    /**
     * Exports a report to CSV.将报告导出为CSV。
     * 
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param response        The HttpServletResponse object
     * @param attachment    true to prompts for open or save; false opens the report
     *                         in the specified format after exporting.
     * @throws ReportSDKExceptionBase
     * @throws IOException
     */
    public static void exportCSV(ReportClientDocument clientDoc, HttpServletResponse response, boolean attachment) throws ReportSDKExceptionBase, IOException {

        System.out.println("exportCSV,Exports a report to CSV.将报告导出为CSV。");

        CharacterSeparatedValuesExportFormatOptions csvOptions = new CharacterSeparatedValuesExportFormatOptions();
        csvOptions.setSeparator(",");
        csvOptions.setDelimiter("\n");
        ExportOptions exportOptions = new ExportOptions();
        exportOptions.setExportFormatType(ReportExportFormat.characterSeparatedValues);        
        exportOptions.setFormatOptions(csvOptions);

        export(clientDoc, exportOptions, response, attachment, "text/csv", "csv");
    }
    
    /**
     * Exports a report to a specified format.将报告导出为指定的格式。
     * 
     * @param clientDoc       The reportClientDocument representing the report being used
     * @param exportOptions   Export options
     * @param response        The response object to write to
     * @param attachment      True to prompts for open or save; false opens the report
     *                        in the specified format after exporting.
     * @param mimeType        MIME type of the format being exported
     * @param extension       file extension of the format (e.g., "pdf" for Acrobat)
     * @throws ReportSDKExceptionBase
     * @throws IOException
     */
    private static void export(ReportClientDocument clientDoc, ExportOptions exportOptions, HttpServletResponse response, boolean attachment, String mimeType, String extension)
        throws ReportSDKExceptionBase, IOException {

        System.out.println("export,Exports a report to a specified format.将报告导出为指定的格式。");

        InputStream is = null;
        try {
            is = new BufferedInputStream(clientDoc.getPrintOutputController().export(exportOptions));
            
            byte[] data = new byte[1024];
            response.setContentType(mimeType);
            if (attachment)
            {
                String name = clientDoc.getReportSource().getReportTitle();
                if (name == null)
                {
                    name = "CrystalReportViewer";
                }
                else
                {
                    name = name.replaceAll("\"", "");
                }
                
                response.setHeader("Content-Disposition",
                        "attachment; filename=\"" + name + "."+extension+"\"");
            }
            OutputStream os = response.getOutputStream();
            while (is.read(data) > -1) {
                os.write(data);
            }
        } finally {
            if (is != null) {
                is.close();
            }
        }

    }
    
    /**
     * Prints to the server printer.打印到服务器打印机。
     * 
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param printerName    Name of printer used to print the report
     * @throws ReportSDKException 
     */
    public static void printToServer(ReportClientDocument clientDoc,String printerName)throws ReportSDKException {

        System.out.println("printToServer,Prints to the server printer.打印到服务器打印机。");

        PrintReportOptions printOptions = new PrintReportOptions();
        // Note: Printer with the <printer name> below must already be
        // configured.
        printOptions.setPrinterName(printerName);
        printOptions.setJobTitle("Sample Print Job from Crystal Reports.");
        printOptions.setPrinterDuplex(PrinterDuplex.useDefault);
        printOptions.setPaperSource(PaperSource.auto);
        printOptions.setPaperSize(PaperSize.paperLetter);
        printOptions.setNumberOfCopies(1);
        printOptions.setCollated(false);

        // Print report
        clientDoc.getPrintOutputController().printReport(printOptions);
    }
    
    /**
     * Prints a range of pages to the server printer.将一系列页面打印到服务器打印机。
     * 
     * @param clientDoc        The reportClientDocument representing the report being used
     * @param printerName    Name of printer used to print the report
     * @param startPage        Starting page
     * @param endPage        Ending page.
     * @throws ReportSDKException 
     */
    public static void printToServer(ReportClientDocument clientDoc,String printerName,int startPage, int endPage)throws ReportSDKException {

        System.out.println("printToServer,Prints a range of pages to the server printer.将一系列页面打印到服务器打印机。");

        PrintReportOptions printOptions = new PrintReportOptions();
        // Note: Printer with the <printer name> below must already be
        // configured.
        printOptions.setPrinterName(printerName);
        printOptions.setJobTitle("Sample Print Job from Crystal Reports.");
        printOptions.setPrinterDuplex(PrinterDuplex.useDefault);
        printOptions.setPaperSource(PaperSource.auto);
        printOptions.setPaperSize(PaperSize.paperLetter);
        printOptions.setNumberOfCopies(1);
        printOptions.setCollated(false);
        PrintReportOptions.PageRange printPageRange = new PrintReportOptions.PageRange(startPage,endPage);
        printOptions.addPrinterPageRange(printPageRange);

        // Print report
        clientDoc.getPrintOutputController().printReport(printOptions);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值