代码改变世界

cognos 调用API生成报表

2014-05-29 14:27  卡尔丶  阅读(719)  评论(0编辑  收藏  举报


package com.huawei.sdprpt.report.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.Locale;

import sun.misc.BASE64Decoder;

import com.cognos.developer.schemas.bibus._3.AsynchDetailReportOutput;
import com.cognos.developer.schemas.bibus._3.AsynchOptionEnum;
import com.cognos.developer.schemas.bibus._3.AsynchOptionInt;
import com.cognos.developer.schemas.bibus._3.AsynchReply;
import com.cognos.developer.schemas.bibus._3.AsynchReplyStatusEnum;
import com.cognos.developer.schemas.bibus._3.AsynchSecondaryRequest;
import com.cognos.developer.schemas.bibus._3.BaseClass;
import com.cognos.developer.schemas.bibus._3.ContentManagerServiceStub;
import com.cognos.developer.schemas.bibus._3.Graphic;
import com.cognos.developer.schemas.bibus._3.Option;
import com.cognos.developer.schemas.bibus._3.Output;
import com.cognos.developer.schemas.bibus._3.OutputEncapsulationEnum;
import com.cognos.developer.schemas.bibus._3.ParameterValue;
import com.cognos.developer.schemas.bibus._3.PropEnum;
import com.cognos.developer.schemas.bibus._3.QueryOptions;
import com.cognos.developer.schemas.bibus._3.RunOptionBoolean;
import com.cognos.developer.schemas.bibus._3.RunOptionEnum;
import com.cognos.developer.schemas.bibus._3.RunOptionLanguageArray;
import com.cognos.developer.schemas.bibus._3.RunOptionOutputEncapsulation;
import com.cognos.developer.schemas.bibus._3.RunOptionStringArray;
import com.cognos.developer.schemas.bibus._3.SearchPathMultipleObject;
import com.cognos.developer.schemas.bibus._3.SearchPathSingleObject;
import com.cognos.developer.schemas.bibus._3.Sort;
import com.huawei.bme.commons.util.debug.DebugLog;
import com.huawei.bme.commons.util.debug.LogFactory;

/**
 * TODO 添加类的一句话简单描述。
 * <p>
 * TODO 详细描述
 * <p>
 * TODO 示例代码
 *
 * <pre>
 * </pre>
 *
 * @author lWX162655
 * @version ONIP BME V300R001 2013-7-31
 * @since ONIP BME V300R001C00
 */
public class RunReport {

    /**
     * 运行报表
     *
     * @param connect
     *            报表服务器连接AL
     * @param reportSearchPath
     *            报表搜索路径
     * @param reportType
     *            报表类型:1:XLS 2:HTML
     * @param parameters
     *            报表参数helper
     * @return
     * @throws IOException
     */

    /**
     * 调测日志记录器。
     */
    private static final DebugLog DEBUGGER = LogFactory
            .getDebugLog(RunReport.class);

    public String run(CognosLog connect, String reportSearchPath,
            String reportType, ParameterValue[] parameters,
            String partOfFileoutPutName, String compagers, String savePath)
            throws IOException {
        String output = null;
        if ((connect != null) && (reportSearchPath != null)) {
            /*
             * 通过reportSearchPath【报表存放路劲】获得报表对象
             */
            BaseClass[] reportDomain = getRoportModel(reportSearchPath,
                    connect.getCMService());
            if (reportDomain.length > 0) {
                ParameterValue[] emptyParameterValues = new ParameterValue[] {}; // 空参
                ParameterValue[] reportParameterValues = null;//
                if (parameters != null) {
                    // 设置报表参数
                    reportParameterValues = parameters;
                }
                // 如果传入的参数数组为空则数组为null
                if ((reportParameterValues == null)
                        || (reportParameterValues.length <= 0)) {
                    // emptyParameterValues 上面定义的一组空参(执行报表必须要有参数数组,数组内容可为空)
                    reportParameterValues = emptyParameterValues;
                }
                // 执行报表
                /*
                 * reportSearchPath:报表存放地址 connect:连接对象
                 * reportType:报表文件类型(html,excel) reportParameterValues:参数数组
                 */

                // File savePathFile = new File(savePath);
                //
                // if(!savePathFile.isDirectory()){
                // savePathFile.mkdirs();
                // }
//                System.out.println("reportSearchPath:" + reportSearchPath +"|reportType:" + reportType  );
//                for (int i = 0; i < reportParameterValues.length; i++) {
////                    SimpleParmValueItem item = (SimpleParmValueItem) reportParameterValues[i];
//                    SimpleParmValueItem item = (SimpleParmValueItem) reportParameterValues[i].getValue()[0];
//                    System.out.println(reportParameterValues[i].getName()+ " | " + item.getUse());
//                }
//                System.out.println("savePath:" + savePath +"partOfFileoutPutName"+ partOfFileoutPutName);
                output = executeReport(reportSearchPath, connect, reportType,
                        reportParameterValues, compagers, savePath,
                        partOfFileoutPutName);
            }
        }
        return output;
    }

    /**
     * 执行报表
     *
     * @param reportSearchPath
     *            报表搜索路径
     * @param connect
     *            报表服务器连接AL
     * @param reportType
     *            报表类型:1:XLS 2:HTML
     * @param paramValueArray
     *            报表参数
     * @param compagers
     * @param savePath
     *            保存路径
     * @param partOfFileoutPutName
     *            报表英文名称
     * @return
     * @throws IOException
     */
    private String executeReport(String reportSearchPath, CognosLog connect,
            String reportType, ParameterValue[] paramValueArray,
            String compagers, String savePath, String partOfFileoutPutName)
            throws IOException {
        Option[] execReportRunOptions = getRunOptions(reportType); // 报表运行配置
        AsynchReply rsr = null; // 报表内容
        // main
        rsr = connect.getReportService().run(
                new SearchPathSingleObject(reportSearchPath), paramValueArray,
                execReportRunOptions);
        // 输出对象没有立刻获得时,执行等待,直到获得输出对象为止
        if (!rsr.getStatus().equals(AsynchReplyStatusEnum.complete)
                && !rsr.getStatus().equals(
                        AsynchReplyStatusEnum.conversationComplete)) {
            while (!rsr.getStatus().equals(AsynchReplyStatusEnum.complete)
                    && !rsr.getStatus().equals(
                            AsynchReplyStatusEnum.conversationComplete)) {
                // 执行等待之前,进行确认
                if (!hasSecondaryRequest(rsr, "wait")) {
                    return null;
                }
                rsr = connect.getReportService().wait(rsr.getPrimaryRequest(),
                        new ParameterValue[] {}, new Option[] {});
            }
            // 确保获得输出对象前,输出对象已经完成提交
            if (outputIsReady(rsr)) {
                rsr = connect.getReportService().getOutput(
                        rsr.getPrimaryRequest(), new ParameterValue[] {},
                        new Option[] {});
            } else {
                return null;
            }
        }
        // 导出
        return textOrBinaryOutput(connect, rsr, partOfFileoutPutName,
                reportType, compagers, savePath);
    }

    private Option[] getRunOptions(String reportType) {
        // 定义运行报表选项数组
        Option[] execReportRunOptions = new Option[7];
        // 指定是否应该将报表输出保存到内容库中
        RunOptionBoolean saveOutputRunOption = new RunOptionBoolean();
        // 导出文件格式
        RunOptionStringArray outputFormat = new RunOptionStringArray();
        // 是否跳过提示页面
        RunOptionBoolean promptFlag = new RunOptionBoolean();
        // 指定存储输出的位置
        RunOptionOutputEncapsulation outputEncapsulation = new RunOptionOutputEncapsulation();
        saveOutputRunOption.setName(RunOptionEnum.saveOutput);
        saveOutputRunOption.setValue(false);// true为保存,false反之
        outputFormat.setName(RunOptionEnum.outputFormat);
        String[] reportFormat = null;
        reportFormat = setFormatByType(reportType);
        outputFormat.setValue(reportFormat);// setValue值应为String类型的数组
        promptFlag.setName(RunOptionEnum.prompt);
        promptFlag.setValue(false);// false:跳过提示页面运行报表
        // 开始之前等待报表完成的初始时间,以秒为单位,默认值为 7 秒
        AsynchOptionInt primaryWaitThreshold = new AsynchOptionInt();
        primaryWaitThreshold.setName(AsynchOptionEnum.primaryWaitThreshold);
        primaryWaitThreshold.setValue(20);

        // 在匿名会话的过程中,等待状态检查的时间,以秒为单位
        AsynchOptionInt secondaryWait = new AsynchOptionInt();
        secondaryWait.setName(AsynchOptionEnum.secondaryWaitThreshold);
        secondaryWait.setValue(65);

        // 设置语言本地化
        RunOptionLanguageArray outputLocale = new RunOptionLanguageArray();
        outputLocale.setName(RunOptionEnum.outputLocale);
        String language = Locale.getDefault().toString();
        if("zh_CN".equals(language)){
            language = "zh-cn";
        }else{
            language = "en-us";
        }
        outputLocale.setValue(new String[] { language });

        outputEncapsulation.setName(RunOptionEnum.outputEncapsulation);
        /*
         * 枚举none:输出不存入临时内容库对象中 (如果报表输出的内容较大如果保存至临时内容库会造成内存溢出
         */
        outputEncapsulation.setValue(OutputEncapsulationEnum.none);
        // 添加各个运行选项
        execReportRunOptions[0] = saveOutputRunOption;
        execReportRunOptions[1] = outputFormat;
        execReportRunOptions[2] = promptFlag;
        execReportRunOptions[3] = primaryWaitThreshold;
        execReportRunOptions[4] = outputLocale;
        execReportRunOptions[5] = outputEncapsulation;
        execReportRunOptions[6] = secondaryWait;
        // 返回 选项 数组
        return execReportRunOptions;
    }

    private boolean outputIsReady(AsynchReply response) {
        // for (int i = 0; i < response.getDetails().length; i++) {
        // if ((response.getDetails()[i] instanceof AsynchDetailReportStatus)
        // && (((AsynchDetailReportStatus) response.getDetails()[i])
        // .getStatus() == AsynchDetailReportStatusEnum.responseReady)
        // && (hasSecondaryRequest(response, "getOutput"))) {
        return true;
        // }
        // }
        // return false;
    }

    /**
     * 设置导出格式
     *
     * @param fileType
     *            1:XLS 2:HTML
     * @return
     */
    private String[] setFormatByType(String fileType) {
        return new String[] { fileType };
        /*
         * 格式还可以为CSV , HTMLFragment, MHT, PDF, singleXLS, XHTML, XLS, XLWA, XML
         */
    }

    private String textOrBinaryOutput(CognosLog connect, AsynchReply rsr,
            String partOfFileoutPutName, String reportType, String compagers,
            String savePath) throws IOException {
        String textOutput = null;

        if (reportType.equalsIgnoreCase("HTML")) {
            textOutput = getOutputPage(connect, rsr, partOfFileoutPutName,
                    reportType, compagers, savePath);
        } else {
            textOutput = saveBinaryOutput(connect, rsr, partOfFileoutPutName,
                    reportType, compagers, savePath);
        }
        return textOutput;
    }

    private String saveBinaryOutput(CognosLog connection, AsynchReply response,
            String partOfFileoutPutName, String reportType, String compagers,
            String savePath) throws IOException {
        String fileSaveUrl = null;
        byte[] binaryOutput = null;
        AsynchDetailReportOutput reportOutput = null;
        for (int i = 0; i < response.getDetails().length; i++) {
            if (response.getDetails()[i] instanceof AsynchDetailReportOutput) {
                reportOutput = (AsynchDetailReportOutput) response.getDetails()[i];
                break;
            }
        }

        if ("PDF".equalsIgnoreCase(reportType)
                || "CSV".equalsIgnoreCase(reportType)) {
            BASE64Decoder d = new BASE64Decoder();
            String str = null;
            if (null != reportOutput && null != reportOutput.getOutputPages()
                    && reportOutput.getOutputPages().length > 0) {
                str = reportOutput.getOutputPages()[0];
            } else {
                if (DEBUGGER.isDebugEnable()) {
                    DEBUGGER.debug("reportOutput.getOutputPages() is null");
                }
            }
            binaryOutput = d.decodeBuffer(str);
        } else {
            if (reportOutput != null)
                binaryOutput = (reportOutput.getOutputPages()[0])
                        .getBytes("UTF-8");
        }
        if (binaryOutput == null) {
            return null;
        }
        // 创建文件
        createNewFile(savePath);
        File oFile = new File(setFilenameByType(savePath, partOfFileoutPutName,
                reportType, compagers));

        // if(oFile.exists())
        // {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(oFile);
            fos.write(binaryOutput);
            fos.flush();
        } finally {
            if (fos != null)
                fos.close();
        }
        // 获取绝对路劲
        fileSaveUrl = oFile.getAbsolutePath();
        // }

        return fileSaveUrl;
    }

    private String getOutputPage(CognosLog connect, AsynchReply response,
            String partOfFileoutPutName, String reportType, String compagers,
            String savePath) throws IOException {
        String fileSaveUrl = null;
        String textOutput = "";
        AsynchDetailReportOutput reportOutput = null;
        for (int i = 0; i < response.getDetails().length; i++) {
            if (response.getDetails()[i] instanceof AsynchDetailReportOutput) {
                reportOutput = (AsynchDetailReportOutput) response.getDetails()[i];
                break;
            }
        }
        if (reportOutput == null) {
            return null;
        }
        if (reportOutput.getOutputObjects().length > 0) {
            textOutput = replaceLocalGraphicsInOutput(connect, reportOutput,
                    savePath, partOfFileoutPutName, compagers);
        } else {
            textOutput = reportOutput.getOutputPages()[0];
        }
        createNewFile(savePath);
        File oFile = new File(setFilenameByType(savePath, partOfFileoutPutName,
                reportType, compagers));

        // if(oFile.exists())
        // {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(oFile);
            if (textOutput != null)
                fos.write(textOutput.getBytes("UTF-8"));
            fos.flush();
        } finally {
            if (fos != null)
                fos.close();
        }
        fileSaveUrl = oFile.getAbsolutePath();
        // }
        return fileSaveUrl;
    }

    private void createNewFile(String savePath) {
        File file = new File(savePath);
        if (!file.exists()) {
            boolean b = file.mkdirs();
            if(b == false){
                if (DEBUGGER.isErrorEnable())
                    {
                        DEBUGGER.error("crate" + file.getName() + " Failed!");
                    }
                }
        }
    }

    private String setFilenameByType(String filePath,
            String partOfFileoutPutName, String fileType, String compagers) {
        if ("singleXLS".equalsIgnoreCase(fileType)) {
            return filePath + File.separator + partOfFileoutPutName + "_"
                    + compagers + ".xls";
        } else if ("HTML".equalsIgnoreCase(fileType)
                || "HTMLFragment".equalsIgnoreCase(fileType)) {
            return filePath + File.separator + partOfFileoutPutName + "_"
                    + compagers + ".html";
        } else if ("MHT".equalsIgnoreCase(fileType)) {
            return filePath + File.separator + partOfFileoutPutName + "_"
                    + compagers + ".mht";
        } else if ("CSV".equalsIgnoreCase(fileType)) {
            return filePath + File.separator + partOfFileoutPutName + "_"
                    + compagers + ".csv";
        } else if ("PDF".equalsIgnoreCase(fileType)) {
            return filePath + File.separator + partOfFileoutPutName + "_"
                    + compagers + ".pdf";
        } else {
            return filePath + File.separator + partOfFileoutPutName + "_"
                    + compagers + ".unknown";
        }
    }

    private String replaceLocalGraphicsInOutput(CognosLog connect,
            AsynchDetailReportOutput reportOutput, String savePath,
            String partOfFileoutPutName, String compages) throws IOException {
        BaseClass[] bcGraphic;
        SearchPathMultipleObject graphicSearchPath = new SearchPathMultipleObject();
        graphicSearchPath.set_value(reportOutput.getOutputObjects()[0]
                .getSearchPath().getValue());
        bcGraphic = connect.getCMService().query(graphicSearchPath,
                new PropEnum[] { PropEnum.searchPath }, new Sort[] {},
                new QueryOptions());
        Output out = null;
        StringBuffer finalHtml = new StringBuffer();
        if ((bcGraphic.length > 0) && (bcGraphic[0] instanceof Output)) {
            SearchPathMultipleObject outSearchPath = new SearchPathMultipleObject();
            out = (Output) bcGraphic[0];
            outSearchPath
                    .set_value(out.getSearchPath().getValue() + "/graphic");
            BaseClass[] g = connect.getCMService().query(
                    outSearchPath,
                    new PropEnum[] { PropEnum.searchPath, PropEnum.data,
                            PropEnum.dataType }, new Sort[] {},
                    new QueryOptions());
            
            String[] pages = reportOutput.getOutputPages();
            String html = pages[0];
            String start = null;
            String end = null;
            String graphicFile = null;
            // 替换html文件中img标签的属性
            for (int i = 0; i < g.length; i++) {
                String pictrueName = partOfFileoutPutName + "_" + compages + i
                        + ".jpg";
                graphicFile = savePath + "/" + pictrueName;
                // 图表保存本地
                FileOutputStream fos = null;
                try {
                    File gFile = new File(graphicFile);
                    fos = new FileOutputStream(gFile);
                    fos.write(((Graphic) g[0]).getData().getValue());
                    fos.flush();
                } finally {
                    if (fos != null)
                        fos.close();
                }
                int index = 0;
                if (html.contains("<img")) {
                    index = html.indexOf("<img", 0);
                    start = html.substring(0, index);
                    end = html.substring(html.indexOf(">", index) + 1);
                    finalHtml.append(start + "<img src='" + pictrueName + "'>");
                    html = end;
                }
            }
            finalHtml.append(html);
            return finalHtml.toString();
        }
        return finalHtml.toString();
    }

    private BaseClass[] getRoportModel(String searchPath,
            ContentManagerServiceStub cmService) throws RemoteException {
        PropEnum[] props = { PropEnum.searchPath };
        BaseClass[] bc = null;
        SearchPathMultipleObject spMulti = new SearchPathMultipleObject();
        spMulti.set_value(searchPath);
        bc = cmService.query(spMulti, props, new Sort[] {}, new QueryOptions());
        return bc;
    }

    private boolean hasSecondaryRequest(AsynchReply response,
            String secondaryRequest) {
        AsynchSecondaryRequest[] secondaryRequests = response
                .getSecondaryRequests();
        for (int i = 0; i < secondaryRequests.length; i++) {
            if (secondaryRequests[i].getName().compareTo(secondaryRequest) == 0) {
                return true;
            }
        }
        return false;
    }
}