001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.plugin.report; 017 018import java.io.BufferedWriter; 019import java.io.File; 020import java.io.FileNotFoundException; 021import java.io.FileOutputStream; 022import java.io.OutputStreamWriter; 023import java.io.UnsupportedEncodingException; 024import org.opengion.hayabusa.common.HybsSystemException; 025import org.opengion.hayabusa.common.HybsSystem; 026import org.opengion.hayabusa.report.AbstractCSVPrintPointService; 027import org.opengion.fukurou.util.StringUtil; 028 029/** 030 * ユニリタ「Report & Form Warehouse」に対応したCSV形式でデータを作成します。 031 * 032 * CSVはシステムリソースRFW_CSV_OUTPUTDIRで指定した場所に[LISTID]_[GRPID]_[YKNO].csvで出力されます。 033 * 特殊な動作として、デーモングループに"BIG"の文字が入っている場合はCSV出力先ディレクトリ末尾に"_BIG"を付加します。 034 * 2つのフォルダは予め作成しておきます。 035 * 036 * PDF等の最終的な出力先、つまりCSVのコントロールヘッダのRDSetOutputFileNameはGE50で指定します。 037 * (Defaultのプラグインと出力が異なるので注意が必要です) 038 * 039 * データに関しては、全てダブルクウォートで囲って出力されます。 040 * ダブルクウォートそのものは二重化でエスケープします。 041 * ヘッダ、フッタが存在する場合、ボディ、ヘッダ、フッタの順番に連結して出力し、カラム名はヘッダはH_、フッタはF_を先頭に追加します。 042 * 043 * 区分Excelの場合にどの文字列でヘッダーを出すかはシステムリソースRFW_EXCEL_TYPEで決めます。 044 * 指定なしの場合はXLSとなります。 045 * 区分Excel(XLSX)の場合はXLSX固定です。 046 * 047 * @og.group 帳票システム 048 * 049 * @version 5.9.0.0 050 * @author Masakazu Takahashi 051 * @since JDK6.0, 052 */ 053public class CSVPrintPointService_RFW extends AbstractCSVPrintPointService { 054 055 private static final String CR = System.getProperty("line.separator"); 056 private final StringBuilder strCSV = new StringBuilder(); // CSVはこれに吐く 057 058 private static final String csvEncode = HybsSystem.sys("REPORT_CSV_TEXT_ENCODE"); 059 060 private static final String RFW_CSV_OUTPUTDIR = HybsSystem.sys("RFW_CSV_OUTPUTDIR"); 061 062 private static final String RFW_EXCEL_TYPE = StringUtil.nval( HybsSystem.sys("RFW_EXCEL_TYPE"), "XLS" ) ; 063 064 /** 065 * 発行処理 066 * ファイル出力 067 * 068 * @og.rev 5.9.2.2 ファイル名に標準OrderBy同様にGRPIDを付ける。デーモングループに「BIG」が入っている場合は出力先変更 069 * 070 * @return 結果 [true:正常/false:異常] 071 */ 072 @Override 073 public boolean execute(){ 074 System.out.print( "CSV create ... " ); 075 BufferedWriter bw = null; 076 boolean flg = false; 077 078 try { 079 makeheader(); 080 makebody(); 081 082// bw = getWriter( RFW_CSV_OUTPUTDIR + File.separator + listid + "_" + ykno + ".csv" ,false,csvEncode); 083 // 汎用化も考えたが、予期せぬ出力があると困るのでBIG決め打ち。フォルダ存在しない場合はエラー 084 if( dmngrp != null && dmngrp.indexOf( "BIG" ) >= 0 ){ // 5.9.2.2 085 bw = getWriter( RFW_CSV_OUTPUTDIR + "_BIG" + File.separator + listid + "_" + grpid + "_" + ykno + ".csv" ,false,csvEncode); 086 } 087 else{ 088 bw = getWriter( RFW_CSV_OUTPUTDIR + File.separator + listid + "_" + grpid + "_" + ykno + ".csv" ,false,csvEncode); 089 } 090 bw.write( strCSV.toString() ); 091 bw.flush(); 092 bw.close(); 093 094 flg = true; 095 096// if( prgfile != null && prgfile.length() > 0){ 097// makeShellCommand(); 098// flg = programRun(); 099// } 100 101 } 102 catch ( Throwable ex ) { 103 errMsg.append( "CSV Print Request Execution Error. " ).append( CR ); 104 errMsg.append( "==============================" ).append( CR ); 105 errMsg.append( "SYSTEM_ID=[" ).append( systemId ).append( "] , " ); 106 errMsg.append( "YKNO=[" ).append( ykno ).append( "] , " ); 107 errMsg.append( ex.toString() ); 108 errMsg.append( CR ); 109// throw new RuntimeException( errMsg.toString() ); 110 throw new RuntimeException( errMsg.toString(), ex ); 111 } 112 return flg; 113 } 114 115 /** 116 * ヘッダの出力 117 * 118 * @og.rev 5.9.1.2 (2015/10/23) RDSetOutputPrinterの値をIDに変更 119 * @og.rev 5.9.3.0 (2015/12/04) option追加 120 * @og.rev 5.9.3.2 (2015/12/21) XLSX対応 121 * @og.rev 5.9.4.2 (2016/01/13) XLSXは区分に持たせるようにする 122 */ 123 private void makeheader(){ 124 //ヘッダデータを出力する場合はここで指定する。 125 strCSV.append( "<rdstart>" ).append( CR ); 126 127 strCSV.append( "RDSetForm=\"" ).append(modelname).append("\"").append( CR ); 128 129 //5.9.3.1 (2015/12/16) 130 strCSV.append( "RDSetUserName=\"" ).append(systemId).append("\"").append( CR ); 131 strCSV.append( "RDSetComputer=\"" ).append( listid + "_" + grpid + "_" + ykno ).append("\"").append( CR ); 132 strCSV.append( "RDSetDocName=\"" ).append(listid).append("\"").append( CR ); 133 134 135 // PDFの場合 136 if( FGRUN_PDF.equals( fgrun ) ){ 137 strCSV.append( "RDSetOutputMode=PDF" ).append( CR ); 138 strCSV.append( "RDSetOutputFileName=\"" ).append( outdir ).append("\"").append( CR ); 139 } 140 // Excel(XLS) 141 else if( FGRUN_EXCEL.equals(fgrun) ){ 142// strCSV.append( "RDSetOutputMode=XLS" ).append( CR ); 143// if( option != null && option.indexOf("RDSetOutputMode") < 0 ){ 144 strCSV.append( "RDSetOutputMode=" + RFW_EXCEL_TYPE ).append( CR ); 145// } 146 strCSV.append( "RDSetOutputFileName=\"" ).append( outdir ).append("\"").append( CR ); 147 } 148 // Excel(XLSX) 5.9.4.2 (2016/01/13) 149 else if( FGRUN_EXCEL2.equals(fgrun) ){ 150 strCSV.append( "RDSetOutputMode=XLSX" ).append( CR ); 151 strCSV.append( "RDSetOutputFileName=\"" ).append( outdir ).append("\"").append( CR ); 152 } 153 // 印刷 154 else{ 155 strCSV.append( "RDSetOutputMode=SPOOL" ).append( CR ); 156 //strCSV.append( "RDSetOutputPrinter=\"" ).append(prtName).append( "\"" ).append( CR ); 157 // プリンタ名ではなく、プリンタIDを出力するように変更 158 strCSV.append( "RDSetOutputPrinter=\"" ).append(prtid).append( "\"" ).append( CR ); 159 } 160 161 if( option != null && option.length() > 0 ){ 162 strCSV.append( option ).append( CR ); // 5.9.3.0 (2015/12/04) 163 } 164 165 strCSV.append( "<rdend>" ).append( CR ); 166 167 //1行目にカラム名を出力します。クウォートで囲わない。 168 // メインテーブルはNULLではない 169 for( int clmNo=0; clmNo<table.getColumnCount(); clmNo++ ) { 170 // 先頭以外はカンマを付ける 171 if( clmNo > 0 ){ strCSV.append( "," ); } 172 strCSV.append( table.getColumnName( clmNo )); 173 } 174 if( tableH != null){ 175 for( int clmNo=0; clmNo<tableH.getColumnCount(); clmNo++ ) { 176 strCSV.append( "," ); 177 strCSV.append("H_").append( tableH.getColumnName( clmNo )); 178 } 179 } 180 if( tableF != null){ 181 for( int clmNo=0; clmNo<tableF.getColumnCount(); clmNo++ ) { 182 strCSV.append( "," ); 183 strCSV.append("F_").append( tableF.getColumnName( clmNo )); 184 } 185 } 186 strCSV.append( CR ); 187 } 188 189 190 191 /** 192 * 本体の出力を行います 193 * HTMLエスケープされている場合は戻します 194 */ 195 private void makebody(){ 196 197 for( int rowNo=0; rowNo<table.getRowCount(); rowNo++ ) { 198 // カラム単位の処理 199 for( int clmNo=0; clmNo<table.getColumnCount(); clmNo++ ) { 200 // 先頭以外はカンマを付ける 201 if( clmNo > 0 ){ strCSV.append( "," ); } 202 // 全てダブルクウォートで囲う 203 strCSV.append("\"").append( StringUtil.replace( StringUtil.getReplaceEscape( table.getValue( rowNo, clmNo )) ,"\"","\"\"" ) ).append("\""); 204 } 205 206 //ヘッダ、フッタは毎行に必ず付加します。 207 //例え複数行あったとしても先頭行のみ有効です 208 //ヘッダ 209 if( tableH != null){ 210 int rowNoH=0; 211 for( int clmNo=0; clmNo<tableH.getColumnCount(); clmNo++ ) { 212 // 必ずカンマを付ける 213 strCSV.append( "," ); 214 // 全てダブルクウォートで囲う 215 strCSV.append("\"").append( StringUtil.replace( StringUtil.getReplaceEscape( tableH.getValue( rowNoH, clmNo )) ,"\"","\"\"" ) ).append("\""); 216 } 217 } 218 219 //フッタ 220 if( tableF != null ){ 221 int rowNoF=0; 222 for( int clmNo=0; clmNo<tableF.getColumnCount(); clmNo++ ) { 223 // 必ずカンマを付ける 224 strCSV.append( "," ); 225 // 全てダブルクウォートで囲う 226 strCSV.append("\"").append( StringUtil.replace( StringUtil.getReplaceEscape( tableF.getValue( rowNoF, clmNo )) ,"\"","\"\"" ) ).append("\""); 227 } 228 } 229 230 strCSV.append( CR ); 231 } 232 } 233 234 235 /** 236 * ファイル書き込み用のライターを返します。 237 * 238 * @param fileName ファイル名 239 * @param append アベンドするか 240 * @param encode エンコード 241 * 242 * @return ライター 243 */ 244 private BufferedWriter getWriter( final String fileName, final boolean append, final String encode) { 245 File file = new File ( fileName ); 246 BufferedWriter bw; 247 248 try { 249 bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file, append ), encode ) ); 250 } 251 catch ( UnsupportedEncodingException ex ) { 252 errMsg.append( "[ERROR] Input File is written by Unsupported Encoding" ); 253 throw new HybsSystemException( ex ); 254 } 255 catch ( FileNotFoundException ex ) { 256 errMsg.append( "[ERROR] File not Found" ); 257 throw new HybsSystemException( ex ); 258 } 259 return bw; 260 } 261 262}