import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.hanei.jaxcel.exception.JaxcelInputException;
-import org.hanei.jaxcel.util.JaxcelUtil;
+import org.hanei.jaxcel.util.ExcelUtil;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
/**
* Excelテンプレートシートの指示子(Template Language)、EL式(Expression Language)の検索、パースを行う
*
+ * @since 1.00.00
* @author Noboru Saito
- *
+ * @deprecated
*/
public class TLParser {
private static final int PARSE_MAX = 10;
private static final short FORMAT_GENERAL = 0;
+ private static final short FORMAT_TEXT = 49;
private Sheet sheet = null;
private JaxcelContext context = null;
* 日付形式書式パターン
*/
private final String[] DATE_FORMATS = {
- "yyyy-MM-dd",
- "yyyy/MM/dd",
- "yyyy-MM-dd HH:mm:ss.SSS",
+ "yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
+ "yyyy-MM-dd'T'HH:mm:ss.SSXXX",
+ "yyyy-MM-dd'T'HH:mm:ss.SXXX",
+ "yyyy-MM-dd'T'HH:mm:ss.SSSXX",
+ "yyyy-MM-dd'T'HH:mm:ss.SSXX",
+ "yyyy-MM-dd'T'HH:mm:ss.SXX",
+ "yyyy-MM-dd'T'HH:mm:ss.SXXX",
+ "yyyy-MM-dd'T'HH:mm:ss.SXX",
+ "yyyy-MM-dd'T'HH:mm:ss.SX",
+ "yyyy-MM-dd'T'HH:mm:ssXXX",
+ "yyyy-MM-dd'T'HH:mm:ssXX",
+ "yyyy-MM-dd'T'HH:mm:ssX",
+ "yyyy-MM-dd'T'HH:mm:ss.S",
+ "yyyy-MM-dd'T'HH:mm:ss",
+ "yyyy-MM-dd'T'HH:mm",
+ "yyyy-MM-dd HH:mm:ss.S",
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd HH:mm",
- "yyyy/MM/dd HH:mm:ss.SSS",
+ "yyyy-MM-dd",
+ "yyyy/MM/dd HH:mm:ss.S",
"yyyy/MM/dd HH:mm:ss",
"yyyy/MM/dd HH:mm",
- "HH:mm:ss.SSS",
+ "yyyy/MM/dd"
+ };
+ private final String[] TIME_FORMATS = {
+ "HH:mm:ss.S",
"HH:mm:ss",
"HH:mm"
};
reParseFlg = false;
}
// 置換後の値がBool型
- else if(StringUtils.equalsIgnoreCase(newCellVal, "ture") || StringUtils.equalsIgnoreCase(newCellVal, "false")) {
+ else if(StringUtils.equalsIgnoreCase(newCellVal, "true") || StringUtils.equalsIgnoreCase(newCellVal, "false")) {
// もともと文字列セルならBoolセルに変更し値をセット
if(cell.getCellType() == Cell.CELL_TYPE_STRING) {
cell.setCellType(Cell.CELL_TYPE_BLANK);
}
// 置換後の値が上記以外
else {
- try {
- // 置換後の値が日付・時刻型
- if(DateUtils.parseDateStrictly(newCellVal, DATE_FORMATS) != null) {
- // もともと文字列セルなら数値セルに変更し値をセット
- if(cell.getCellType() == Cell.CELL_TYPE_STRING) {
- cell.setCellType(Cell.CELL_TYPE_BLANK);
- cell.setCellType(Cell.CELL_TYPE_NUMERIC);
- // 書式未設定なら文字列のまま挿入
- if(FORMAT_GENERAL == cell.getCellStyle().getDataFormat()) {
- cell.setCellValue(newCellVal);
- log.debug("set value type: String");
- }
- else {
- cell.setCellValue(DateUtils.parseDateStrictly(newCellVal, DATE_FORMATS));
- log.debug("set value type: Date");
- }
+ Date tmpDate = null;
+ int valType = -1;
+ for(int i = 0; i < 3; i++) {
+ switch(i) {
+ case 0:
+ try {
+ // 置換後の値が日付・日付時刻型
+ tmpDate = DateUtils.parseDateStrictly(newCellVal, Locale.getDefault(), DATE_FORMATS);
+ valType = i;
+ } catch (ParseException e1) {}
+ break;
+ case 1:
+ try {
+ // 置換後の値が時刻型
+ tmpDate = DateUtils.parseDateStrictly(newCellVal, TIME_FORMATS);
+ valType = i;
+ } catch (ParseException e1) {}
+ break;
+ default:
+ // 置換後の値が上記以外(文字列)
+ valType = i;
+ break;
+ }
+ if(valType >= 0) break;
+ }
+
+ switch(valType) {
+ case 0:
+ case 1:
+ // 置換後の値が日付・日付時刻・時刻型
+ // もともと文字列セルなら数値セルに変更し値をセット
+ if(cell.getCellType() == Cell.CELL_TYPE_STRING) {
+ cell.setCellType(Cell.CELL_TYPE_BLANK);
+ cell.setCellType(Cell.CELL_TYPE_NUMERIC);
+ // 書式文字列なら文字列のまま挿入
+ if(FORMAT_GENERAL == cell.getCellStyle().getDataFormat() || FORMAT_TEXT == cell.getCellStyle().getDataFormat()) {
+ cell.setCellValue(newCellVal);
+ log.debug("set value type: String");
}
- // もともと計算式セルの場合は計算式として値をセット
else {
- // まずはそのまま
- try {
- cell.setCellFormula(newCellVal);
- log.debug("set value type: Formula");
- }
- // エラー発生で数値としてセット
- catch(FormulaParseException e) {
- log.warn("formula set error: {}", e.getMessage(), e);
- cell.setCellType(Cell.CELL_TYPE_BLANK);
- cell.setCellType(Cell.CELL_TYPE_NUMERIC);
- cell.setCellValue(DateUtils.parseDateStrictly(newCellVal, DATE_FORMATS));
+ switch(valType) {
+ case 0:
+ // 置換後の値が日付・日付時刻型ならDateでセット
+ cell.setCellValue(tmpDate);
log.debug("set value type: Date");
+ break;
+ case 1:
+ // 置換後の値が時刻型ならDoubleでセット(デフォルトタイムゾーン分加算)
+ cell.setCellValue((tmpDate.getTime() + TimeZone.getDefault().getRawOffset()) / (1000.0 * 60 * 60 * 24));
+ log.debug("set value type: double");
+ break;
}
}
- // 再パースフラグクリア
- reParseFlg = false;
}
+ // もともと計算式セルの場合は計算式として値をセット
else {
- // 元のセルタイプのまま値をセット
- throw new ParseException("", 0);
+ // まずはそのまま
+ try {
+ cell.setCellFormula(newCellVal);
+ log.debug("set value type: Formula");
+ }
+ // エラー発生で数値としてセット
+ catch(FormulaParseException e) {
+ log.warn("formula set error: {}", e.getMessage(), e);
+ cell.setCellType(Cell.CELL_TYPE_BLANK);
+ cell.setCellType(Cell.CELL_TYPE_NUMERIC);
+ cell.setCellValue(tmpDate);
+ log.debug("set value type: Date");
+ }
}
- }
- catch(ParseException e) {
+ // 再パースフラグクリア
+ reParseFlg = false;
+ break;
+ default:
+ // 置換後の値が日付・日付時刻・時刻型以外(文字列と判断)
// 元のセルタイプのまま値をセット
if(cell.getCellType() == Cell.CELL_TYPE_STRING) {
cell.setCellValue(newCellVal);
log.debug("set value type: String");
}
else {
+ // 式
try {
cell.setCellFormula(newCellVal);
log.debug("set value type: Formula");
}
}
}
- // newCellValが空白なら
+ // newCellValが空白
else {
+ cell.setCellType(Cell.CELL_TYPE_BLANK);
// 再パースフラグクリア
reParseFlg = false;
}
private void parseForeach() {
log.trace("parseForeach start");
- Row row, toRow;
- Cell cell, toCell;
+ Row fromRow, toRow;
+ Cell fromCell, toCell;
Object evalObject;
Object listObject;
+ Object[] mapKeys = null;
int listSize;
ArrayList<CellRangeAddress> rangeList = new ArrayList<>();
CellRangeAddress fromRange, toRange, tmpBfRange, tmpAfRange;
}
log.debug("list class: {}", listObject.getClass().getName());
+ // listObject Mapならキー取得
+ if(listObject instanceof Map) {
+ mapKeys = ((Map<?, ?>)listObject).keySet().toArray();
+ }
+
// listのサイズ取得
evalObject = elMgr.evaluate("size(" + list + ")");
// evalした結果がintでなければリスト不可なオブジェクトと判断
}
// 繰返し方向縦(行)の場合
else {
- fromRange = new CellRangeAddress(startRowIdx, startRowIdx + rowSpan - 1, 0, JaxcelUtil.getLastColNum(sheet));
+ fromRange = new CellRangeAddress(startRowIdx, startRowIdx + rowSpan - 1, 0, ExcelUtil.getLastColNum(sheet));
}
}
else {
fromRange = new CellRangeAddress(startRowIdx, startRowIdx + rowSpan - 1, startColIdx, startColIdx + colSpan - 1);
}
// シートに収まる範囲にリサイズ
- fromRange = JaxcelUtil.getIntersectRange(sheet, fromRange);
+ fromRange = ExcelUtil.getIntersectRange(sheet, fromRange);
- // 繰返しコピー回数1以上なら
+ // 繰返しコピー回数1以上なら、コピー先範囲シフト・クリア等実施
if(startIdx != endIdx) {
// コピー先範囲の範囲特定
int copyCount = startIdx < endIdx ? endIdx - startIdx : startIdx - endIdx;
if(COL.equalsIgnoreCase(direction)) {
distance *= colSpan;
// 繰返し範囲以降をずらす
- JaxcelUtil.shift(sheet, new CellRangeAddress(fromRange.getFirstRow(), fromRange.getLastRow(), fromRange.getLastColumn() + 1, fromRange.getLastColumn() + 1), COL, distance, block);
+ ExcelUtil.shift(sheet, new CellRangeAddress(fromRange.getFirstRow(), fromRange.getLastRow(), fromRange.getLastColumn() + 1, fromRange.getLastColumn() + 1), COL, distance, block);
}
// 繰返し方向縦(行)の場合
else {
distance *= rowSpan;
// 繰返し範囲以降をずらす
- JaxcelUtil.shift(sheet, new CellRangeAddress(fromRange.getLastRow() + 1, fromRange.getLastRow() + 1, fromRange.getFirstColumn(), fromRange.getLastColumn()), ROW, distance, block);
+ ExcelUtil.shift(sheet, new CellRangeAddress(fromRange.getLastRow() + 1, fromRange.getLastRow() + 1, fromRange.getFirstColumn(), fromRange.getLastColumn()), ROW, distance, block);
}
}
// shift:falseの場合、コピー先範囲をクリア
else {
- JaxcelUtil.clearRange(sheet, toRange, COPY.equalsIgnoreCase(style), true);
+ ExcelUtil.clearRange(sheet, toRange, COPY.equalsIgnoreCase(style), COPY.equalsIgnoreCase(style));
}
// style:copyの場合、コピー元範囲の結合保持・解除
if(COPY.equalsIgnoreCase(style)) {
}
}
- // コピー元範囲を繰返しコピー
- int cpCount = 0;
- boolean contFlag;
- // 範囲行でループ
- for(int r = fromRange.getFirstRow(); r <= fromRange.getLastRow(); r++) {
- row = sheet.getRow(r);
- // コピー元行がnullで繰返し方向横(列)の場合
- if(row == null && COL.equalsIgnoreCase(direction)) {
- // コピー先行もnullとなるのでセルの処理はせず終了
- log.debug("continue. direction: col from row [{}] is null", (r + 1));
- continue;
- }
-
- // 範囲列でループ
- for(int c = fromRange.getFirstColumn(); c <= fromRange.getLastColumn(); c++) {
- // コピー元行がnullの場合セルもnull
- if(row == null) {
- cell = null;
- } else {
- cell = row.getCell(c);
+ // 繰返し回数でループしコピー
+ boolean copyFlg = true;
+ for(int i = startIdx, cpCount = 0; (startIdx <= endIdx && i <= endIdx || startIdx > endIdx && i >= endIdx); i = (startIdx <= endIdx ? i + 1 : i - 1), cpCount++) {
+ // 範囲行でループ
+ for(int r = fromRange.getFirstRow(); r <= fromRange.getLastRow(); r++) {
+ // 繰返し方向縦(行)の場合、コピー先の範囲チェック
+ if(ROW.equalsIgnoreCase(direction) && (r + rowSpan * cpCount < 0 || r + rowSpan * cpCount > ExcelUtil.getMaxRowIndex(sheet))) {
+ // コピー先行がシート範囲外
+ log.warn("to row outside sheet");
+ // 繰返しコピーフラグfalse
+ copyFlg = false;
+ break;
}
- // 繰返し回数でループ
- cpCount = 0; // コピー実施回数のクリア
- for(int i = startIdx; (startIdx <= endIdx && i <= endIdx || startIdx > endIdx && i >= endIdx); i = (startIdx <= endIdx ? i + 1 : i - 1)) {
- contFlag = false;
-
- // 繰返し方向横(列)(行がデフォルト)
- if(COL.equalsIgnoreCase(direction)) {
- // 範囲チェック
- if(c + colSpan * cpCount < 0 || c + colSpan * cpCount > JaxcelUtil.getMaxColumnIndex(sheet)) {
- log.warn("to cell outside sheet");
- break;
- }
- toRow = row;
- toCell = row.getCell(c + colSpan * cpCount);
- // コピー元セルがnullならコピー先セルもnull
- if(cell == null) {
- if(toCell != null) {
- toRow.removeCell(toCell);
- log.debug("continue. from cell [{}] is null. to cell [{}] remove", (new CellReference(r, c)).formatAsString(), (new CellReference(r, c + colSpan * cpCount)).formatAsString());
- }
- else {
- log.debug("continue. from cell [{}] and to cell [{}] is null", (new CellReference(r, c)).formatAsString(), (new CellReference(r, c + colSpan * cpCount)).formatAsString());
- }
- contFlag = true;
- }
- else {
- if(toCell == null) toCell = row.createCell(c + colSpan * cpCount);
- // block falseなら列情報(幅)もコピー
- if(!block) {
- sheet.setColumnWidth(toCell.getColumnIndex(), sheet.getColumnWidth(cell.getColumnIndex()));
- }
- }
+ // コピー元行
+ fromRow = sheet.getRow(r);
+ // コピー先行
+ toRow = ROW.equalsIgnoreCase(direction) ? sheet.getRow(r + rowSpan * cpCount) : fromRow;
+
+ // コピー元行がnullならコピー先行もnull。continue
+ if(fromRow == null) {
+ if(toRow != null) {
+ log.debug("continue. from row [{}] is null. to row [{}] remove", (r + 1), (toRow.getRowNum() + 1));
+ sheet.removeRow(toRow);
}
- // 繰返し方向縦(行)の場合
else {
- // 範囲チェック
- if(r + rowSpan * cpCount < 0 || r + rowSpan * cpCount > JaxcelUtil.getMaxRowIndex(sheet)) {
- log.warn("to row outside sheet");
- break;
+ log.debug("continue. from row [{}] and to row [{}] is null", (r + 1), ((ROW.equalsIgnoreCase(direction) ? (r + rowSpan * cpCount) : r) + 1));
+ }
+ continue;
+ }
+
+ // コピー先行がnullなら生成
+ if(toRow == null) toRow = sheet.createRow(r + rowSpan * cpCount);
+
+ // コピー元行・コピー先行 行番号が異なり、block falseなら行情報(高さ)もコピー
+ if(fromRow.getRowNum() != toRow.getRowNum() && !block) toRow.setHeight(fromRow.getHeight());
+
+ // 範囲列でループ
+ for(int c = fromRange.getFirstColumn(); c <= fromRange.getLastColumn(); c++) {
+ // 繰返し方向横(列)の場合、コピー先の範囲チェック
+ if(COL.equalsIgnoreCase(direction) && (c + colSpan * cpCount < 0 || c + colSpan * cpCount > ExcelUtil.getMaxColumnIndex(sheet))) {
+ // コピー先列がシート範囲外
+ log.warn("to cell outside sheet");
+ break;
+ }
+
+ // コピー元セル
+ fromCell = fromRow.getCell(c);
+ // コピー先セル
+ toCell = toRow.getCell(COL.equalsIgnoreCase(direction) ? c + colSpan * cpCount : c);
+
+ // コピー元セルがnullならコピー先セルもnull
+ if(fromCell == null) {
+ if(toCell != null) {
+ log.debug("continue. from cell [{}] is null. to cell [{}] remove", (new CellReference(fromRow.getRowNum(), c)).formatAsString(), (new CellReference(toCell.getRowIndex(), toCell.getColumnIndex())).formatAsString());
+ toRow.removeCell(toCell);
}
- // 繰返し先の行がなければ生成
- toRow = sheet.getRow(r + rowSpan * cpCount);
- toCell = null;
- // コピー元行がnullならコピー先行もnull
- if(row == null) {
- if(toRow != null) {
- sheet.removeRow(toRow);
- log.debug("continue. from row [{}] is null. to row [{}] remove", (r + 1));
- }
- else {
- log.debug("continue. from and to row is null");
- }
- contFlag = true;
- }
else {
- if(toRow == null) toRow = sheet.createRow(r + rowSpan * cpCount);
- // block falseなら行情報(高さ)もコピー
- if(!block) {
- toRow.setHeight(row.getHeight());
- }
- toCell = toRow.getCell(c);
- // コピー元セルがnullならコピー先セルもnull
- if(cell == null) {
- if(toCell != null) {
- toRow.removeCell(toCell);
- log.debug("continue. from cell is null. to cell remove");
- }
- else {
- log.debug("continue. from cell [{}] and to cell [{}] is null", (new CellReference(r, c)).formatAsString(), (new CellReference(r + rowSpan * cpCount, c)).formatAsString());
- }
- contFlag = true;
- }
- else {
- if(toCell == null) toCell = toRow.createCell(c);
- }
+ log.debug("continue. from cell [{}] and to cell [{}] is null", (new CellReference(fromRow.getRowNum(), c)).formatAsString(), (new CellReference(toRow.getRowNum(), COL.equalsIgnoreCase(direction) ? c + colSpan * cpCount : c)).formatAsString());
}
+ continue;
}
- if(!contFlag) {
- // スタイルコピーなら
- if(cpCount > 0 && COPY.equalsIgnoreCase(style)) {
- // スタイルのコピー
- toCell.setCellStyle(cell.getCellStyle());
- }
- // 値
- switch(cell.getCellType()) {
- case Cell.CELL_TYPE_BLANK:
- toCell.setCellType(Cell.CELL_TYPE_BLANK);
- break;
- case Cell.CELL_TYPE_BOOLEAN:
- toCell.setCellType(Cell.CELL_TYPE_BOOLEAN);
- toCell.setCellValue(cell.getBooleanCellValue());
- break;
- case Cell.CELL_TYPE_ERROR:
- toCell.setCellType(Cell.CELL_TYPE_ERROR);
- toCell.setCellErrorValue(cell.getErrorCellValue());
- break;
- case Cell.CELL_TYPE_FORMULA:
- toCell.setCellType(Cell.CELL_TYPE_FORMULA);
- // 数式のパース・移動先に合わせる
- toCell.setCellFormula(
- JaxcelUtil.getMoveFormula(
- sheet,
- cell.getCellFormula().replace((i == startIdx ? object : list + "[" + (startIdx - 1) + "]"), list + "[" + (i - 1) + "]"),
- toCell.getRowIndex() - cell.getRowIndex(),
- toCell.getColumnIndex() - cell.getColumnIndex()
- )
- );
- break;
- case Cell.CELL_TYPE_NUMERIC:
- toCell.setCellType(Cell.CELL_TYPE_NUMERIC);
- toCell.setCellValue(cell.getNumericCellValue());
- break;
- case Cell.CELL_TYPE_STRING:
- toCell.setCellType(Cell.CELL_TYPE_STRING);
- toCell.setCellValue(cell.getStringCellValue().replace((i == startIdx ? object : list + "[" + (startIdx - 1) + "]"), list + "[" + (i - 1) + "]"));
- break;
- }
+
+ // コピー先セルがnullなら生成
+ if(toCell == null) toCell = toRow.createCell(COL.equalsIgnoreCase(direction) ? c + colSpan * cpCount : c);
+
+ // コピー元列・コピー先列 列番号が異なり、block falseなら列情報(幅)もコピー ( 繰返しループ1回目のみ)
+ if(cpCount == 0 && fromCell.getColumnIndex() != toCell.getColumnIndex() && !block)
+ sheet.setColumnWidth(toCell.getColumnIndex(), sheet.getColumnWidth(fromCell.getColumnIndex()));
+
+ // スタイルコピーなら
+ if(cpCount > 0 && COPY.equalsIgnoreCase(style)) {
+ // スタイルのコピー
+ toCell.setCellStyle(fromCell.getCellStyle());
+ }
+ // 値のコピー
+ switch(fromCell.getCellType()) {
+ case Cell.CELL_TYPE_BLANK:
+ toCell.setCellType(Cell.CELL_TYPE_BLANK);
+ break;
+ case Cell.CELL_TYPE_BOOLEAN:
+ toCell.setCellType(Cell.CELL_TYPE_BOOLEAN);
+ toCell.setCellValue(fromCell.getBooleanCellValue());
+ break;
+ case Cell.CELL_TYPE_ERROR:
+ toCell.setCellType(Cell.CELL_TYPE_ERROR);
+ toCell.setCellErrorValue(fromCell.getErrorCellValue());
+ break;
+ case Cell.CELL_TYPE_FORMULA:
+ toCell.setCellType(Cell.CELL_TYPE_FORMULA);
+ // 数式のパース・移動先に合わせる
+ toCell.setCellFormula(
+ ExcelUtil.getMoveFormula(
+ sheet,
+ fromCell.getCellFormula().replace(
+ (cpCount == 0 ? object : "(" + list + ")[" + (mapKeys == null ? (startIdx - 1) : "'" + mapKeys[startIdx - 1] + "'") + "]"), "(" + list + ")[" + (mapKeys == null ? (i - 1) : "'" + mapKeys[i - 1] + "'") + "]"),
+ toCell.getRowIndex() - fromCell.getRowIndex(),
+ toCell.getColumnIndex() - fromCell.getColumnIndex()
+ )
+ );
+ log.debug("to cell Formula: {}", toCell.getCellFormula());
+ break;
+ case Cell.CELL_TYPE_NUMERIC:
+ toCell.setCellType(Cell.CELL_TYPE_NUMERIC);
+ toCell.setCellValue(fromCell.getNumericCellValue());
+ break;
+ case Cell.CELL_TYPE_STRING:
+ toCell.setCellType(Cell.CELL_TYPE_STRING);
+ toCell.setCellValue(fromCell.getStringCellValue().replace((cpCount == 0 ? object : "(" + list + ")[" + (mapKeys == null ? (startIdx - 1) : "'" + mapKeys[startIdx - 1] + "'") + "]"), "(" + list + ")[" + (mapKeys == null ? (i - 1) : "'" + mapKeys[i - 1] + "'") + "]"));
+ log.debug("to cell string: {}", toCell.getStringCellValue());
+ break;
}
- cpCount++;
}
}
+ // 繰返しコピーフラグfalseならbreak
+ if(!copyFlg) break;
}
+// // コピー元範囲を繰返しコピー
+// // 範囲行でループ
+// for(int r = fromRange.getFirstRow(); r <= fromRange.getLastRow(); r++) {
+// row = sheet.getRow(r);
+// // コピー元行がnullで繰返し方向横(列)の場合
+// if(row == null && COL.equalsIgnoreCase(direction)) {
+// // コピー先行もnullとなるのでセルの処理はせず終了
+// log.debug("continue. direction: col from row [{}] is null", (r + 1));
+// continue;
+// }
+//
+// // 範囲列でループ
+// for(int c = fromRange.getFirstColumn(); c <= fromRange.getLastColumn(); c++) {
+// // コピー元行がnullの場合セルもnull
+// if(row == null) {
+// cell = null;
+// } else {
+// cell = row.getCell(c);
+// }
+//
+// // 繰返し回数でループ
+// for(int i = startIdx, cpCount = 0; (startIdx <= endIdx && i <= endIdx || startIdx > endIdx && i >= endIdx); i = (startIdx <= endIdx ? i + 1 : i - 1), cpCount++) {
+// // 繰返し方向横(列)(行がデフォルト)
+// if(COL.equalsIgnoreCase(direction)) {
+// // 範囲チェック
+// if(c + colSpan * cpCount < 0 || c + colSpan * cpCount > ExcelUtil.getMaxColumnIndex(sheet)) {
+// log.warn("to cell outside sheet");
+// break;
+// }
+// toRow = row;
+// toCell = row.getCell(c + colSpan * cpCount);
+// // コピー元セルがnullならコピー先セルもnull
+// if(cell == null) {
+// if(toCell != null) {
+// toRow.removeCell(toCell);
+// log.debug("continue. from cell [{}] is null. to cell [{}] remove", (new CellReference(r, c)).formatAsString(), (new CellReference(r, c + colSpan * cpCount)).formatAsString());
+// }
+// else {
+// log.debug("continue. from cell [{}] and to cell [{}] is null", (new CellReference(r, c)).formatAsString(), (new CellReference(r, c + colSpan * cpCount)).formatAsString());
+// }
+// continue;
+// }
+// else {
+// if(toCell == null) toCell = row.createCell(c + colSpan * cpCount);
+// // block falseなら列情報(幅)もコピー
+// if(!block) {
+// sheet.setColumnWidth(toCell.getColumnIndex(), sheet.getColumnWidth(cell.getColumnIndex()));
+// }
+// }
+// }
+// // 繰返し方向縦(行)の場合
+// else {
+// // 範囲チェック
+// if(r + rowSpan * cpCount < 0 || r + rowSpan * cpCount > ExcelUtil.getMaxRowIndex(sheet)) {
+// log.warn("to row outside sheet");
+// break;
+// }
+// // 繰返し先の行がなければ生成
+// toRow = sheet.getRow(r + rowSpan * cpCount);
+// toCell = null;
+// // コピー元行がnullならコピー先行もnull
+// if(row == null) {
+// if(toRow != null) {
+// sheet.removeRow(toRow);
+// log.debug("continue. from row [{}] is null. to row [{}] remove", (r + 1));
+// }
+// else {
+// log.debug("continue. from and to row is null");
+// }
+// continue;
+// }
+// else {
+// if(toRow == null) toRow = sheet.createRow(r + rowSpan * cpCount);
+// // block falseなら行情報(高さ)もコピー
+// if(!block) {
+// toRow.setHeight(row.getHeight());
+// }
+// toCell = toRow.getCell(c);
+// // コピー元セルがnullならコピー先セルもnull
+// if(cell == null) {
+// if(toCell != null) {
+// toRow.removeCell(toCell);
+// log.debug("continue. from cell is null. to cell remove");
+// }
+// else {
+// log.debug("continue. from cell [{}] and to cell [{}] is null", (new CellReference(r, c)).formatAsString(), (new CellReference(r + rowSpan * cpCount, c)).formatAsString());
+// }
+// continue;
+// }
+// else {
+// if(toCell == null) toCell = toRow.createCell(c);
+// }
+// }
+// }
+//
+// // スタイルコピーなら
+// if(cpCount > 0 && COPY.equalsIgnoreCase(style)) {
+// // スタイルのコピー
+// toCell.setCellStyle(cell.getCellStyle());
+// }
+// // 値のコピー
+// switch(cell.getCellType()) {
+// case Cell.CELL_TYPE_BLANK:
+// toCell.setCellType(Cell.CELL_TYPE_BLANK);
+// break;
+// case Cell.CELL_TYPE_BOOLEAN:
+// toCell.setCellType(Cell.CELL_TYPE_BOOLEAN);
+// toCell.setCellValue(cell.getBooleanCellValue());
+// break;
+// case Cell.CELL_TYPE_ERROR:
+// toCell.setCellType(Cell.CELL_TYPE_ERROR);
+// toCell.setCellErrorValue(cell.getErrorCellValue());
+// break;
+// case Cell.CELL_TYPE_FORMULA:
+// toCell.setCellType(Cell.CELL_TYPE_FORMULA);
+// // 数式のパース・移動先に合わせる
+// toCell.setCellFormula(
+// ExcelUtil.getMoveFormula(
+// sheet,
+// cell.getCellFormula().replace(
+// (i == startIdx ? object : list + "[" + (mapKeys == null ? (startIdx - 1) : "'" + mapKeys[startIdx - 1] + "'") + "]"), list + "[" + (mapKeys == null ? (i - 1) : "'" + mapKeys[i - 1] + "'") + "]"),
+// toCell.getRowIndex() - cell.getRowIndex(),
+// toCell.getColumnIndex() - cell.getColumnIndex()
+// )
+// );
+// log.debug("to cell Formula: {}", toCell.getCellFormula());
+// break;
+// case Cell.CELL_TYPE_NUMERIC:
+// toCell.setCellType(Cell.CELL_TYPE_NUMERIC);
+// toCell.setCellValue(cell.getNumericCellValue());
+// break;
+// case Cell.CELL_TYPE_STRING:
+// toCell.setCellType(Cell.CELL_TYPE_STRING);
+// toCell.setCellValue(cell.getStringCellValue().replace((i == startIdx ? object : list + "[" + (mapKeys == null ? (startIdx - 1) : "'" + mapKeys[startIdx - 1] + "'") + "]"), list + "[" + (mapKeys == null ? (i - 1) : "'" + mapKeys[i - 1] + "'") + "]"));
+// log.debug("to cell string: {}", toCell.getStringCellValue());
+// break;
+// }
+// }
+// }
+// }
// スタイルコピーなら
if(COPY.equalsIgnoreCase(style)) {
// 行列加算用
for(int c = 0; c < rangeList.size(); c++) {
tmpBfRange = rangeList.get(c);
// 繰返し回数でループ
- cpCount = 1; // コピー実施回数のクリア
- for(int i = startIdx; (startIdx <= endIdx && i <= endIdx || startIdx > endIdx && i >= endIdx); i = (startIdx <= endIdx ? i + 1 : i - 1)) {
+ for(int i = startIdx, cpCount = 0; (startIdx <= endIdx && i <= endIdx || startIdx > endIdx && i >= endIdx); i = (startIdx <= endIdx ? i + 1 : i - 1), cpCount++) {
// 初回はコピーしない(コピー元だから)
if(i == startIdx) continue;
// コピー先レンジ
tmpBfRange.getLastRow() + (addRow * cpCount),
tmpBfRange.getFirstColumn() + (addCol * cpCount),
tmpBfRange.getLastColumn() + (addCol * cpCount));
- sheet.addMergedRegion(tmpAfRange);
- log.debug("mergedRegion copy. from: [{}] to: [{}]", tmpBfRange.formatAsString(), tmpAfRange.formatAsString());
- cpCount++;
+ if(ExcelUtil.validateRange(sheet, tmpAfRange)) {
+ sheet.addMergedRegion(tmpAfRange);
+ log.debug("mergedRegion copy. from: [{}] to: [{}]", tmpBfRange.formatAsString(), tmpAfRange.formatAsString());
+ }
}
}
}
CTMarker from, to;
try {
// DocumentPartでループ
- for(POIXMLDocumentPart dr : ((XSSFSheet)sheet).getRelations()) {
- if(dr == null) continue;
- log.debug("DocumentPart class: {}", dr.getClass().getName());
+ for(POIXMLDocumentPart part : ((XSSFSheet)sheet).getRelations()) {
+ if(part == null) continue;
+ log.debug("DocumentPart class: {}", part.getClass().getName());
// DocumentPartがDrawingオブジェクトの場合
- if(dr instanceof XSSFDrawing) {
- ctDrawing = ((XSSFDrawing) dr).getCTDrawing();
+ if(part instanceof XSSFDrawing) {
+ ctDrawing = ((XSSFDrawing) part).getCTDrawing();
if(ctDrawing != null) {
// アンカーでループ
int alSize = ctDrawing.getTwoCellAnchorList().size();
case CellRangeUtil.INSIDE:
case CellRangeUtil.OVERLAP:
// 繰返し回数でループ
- cpCount = 1; // コピー実施回数のクリア
- for(int j = startIdx; (startIdx <= endIdx && j <= endIdx || startIdx > endIdx && j >= endIdx); j = (startIdx <= endIdx ? j + 1 : j - 1)) {
+ for(int j = startIdx, cpCount = 0; (startIdx <= endIdx && j <= endIdx || startIdx > endIdx && j >= endIdx); j = (startIdx <= endIdx ? j + 1 : j - 1), cpCount++) {
// 初回はコピーしない(コピー元だから)
if(j == startIdx) continue;
- // TODO これでオブジェクト(アンカー)のコピーができる!!
+ // オブジェクト(アンカー)のコピー
cpAnchor = ctDrawing.addNewTwoCellAnchor();
cpAnchor.set(fAnchor.copy());
from = cpAnchor.getFrom();
tmpAfRange = new CellRangeAddress(from.getRow(), to.getRow(), from.getCol(), to.getCol());
log.debug("object copy from: [{}] to: [{}]", tmpBfRange.formatAsString(), tmpAfRange.formatAsString());
}
- cpCount++;
}
}
}
switch(delete) {
// クリア
case CLEAR:
- JaxcelUtil.clearRange(sheet, (new CellRangeAddress(startRowIdx, startRowIdx + rowSpan - 1, startColIdx, startColIdx + colSpan - 1)), true, true);
+ ExcelUtil.clearRange(sheet, (new CellRangeAddress(startRowIdx, startRowIdx + rowSpan - 1, startColIdx, startColIdx + colSpan - 1)), false, false);
break;
// 左詰め
case LEFT:
// IF範囲以降をずらす
- JaxcelUtil.shift(sheet, new CellRangeAddress(startRowIdx, startRowIdx + rowSpan - 1, startColIdx + colSpan, startColIdx + colSpan), COL, -colSpan, block);
+ ExcelUtil.shift(sheet, new CellRangeAddress(startRowIdx, startRowIdx + rowSpan - 1, startColIdx + colSpan, startColIdx + colSpan), COL, -colSpan, block);
break;
// 上詰め
case UP:
// IF範囲以降をずらす
- JaxcelUtil.shift(sheet, new CellRangeAddress(startRowIdx + rowSpan, startRowIdx + rowSpan, startColIdx, startColIdx + colSpan - 1), ROW, -rowSpan, block);
+ ExcelUtil.shift(sheet, new CellRangeAddress(startRowIdx + rowSpan, startRowIdx + rowSpan, startColIdx, startColIdx + colSpan - 1), ROW, -rowSpan, block);
}
}
log.trace("parseIf end");
* @return 置換後の文字列
*/
private String replaceFirst(String replacement) {
- return mtAll.replaceFirst(replacement == null ? "" : replacement);
+ return mtAll.replaceFirst(replacement == null ? "" : replacement.replace("\\", "\\\\").replace("$", "\\$"));
}
/**