package jp.satomichan.nucalgen;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
+import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
+import jp.satomichan.nucalgen.addition.AcCell;
+import jp.satomichan.nucalgen.addition.AcRow;
+import jp.satomichan.nucalgen.addition.AdditionConfig;
+import jp.satomichan.nucalgen.addition.AdditionUtil;
+
public class Nucalgen {
+ //開始位置 最初の食品の、最初の栄養成分の位置 (E4セル)
+ private static final int ROW_INDEX_START = 3;
private static final int COL_INDEX_START = 4;
public static void main(String[] args) {
options.addOption(Option.builder("c").required().hasArg().longOpt("columns").build());
options.addOption(Option.builder("o").required().hasArg().longOpt("output").build());
options.addOption(Option.builder("l").required().hasArg().longOpt("lines").build());
- options.addOption(Option.builder("p").longOpt("use-processed-table").build());
- options.addOption(Option.builder("pfc").longOpt("with-pfc-balance").build());
- options.addOption(Option.builder("groupsum").longOpt("with-group-sum").build());
+ options.addOption(Option.builder("add").hasArgs().longOpt("addition").build());
+ options.addOption(Option.builder("sheets").hasArgs().build());
options.addOption(Option.builder("bright").hasArg().longOpt("bright-colored-vegetables-list").build());
options.addOption(Option.builder("protect").longOpt("set-protect").build());
- options.addOption(Option.builder("r").longOpt("-use-processed-table").build());
+ options.addOption(Option.builder("processed").longOpt("use-processed-table").build());
- Map<String, String> namedAreaMap = new HashMap<String, String>();
+ NamedAreaStore namedArea = NamedAreaStore.getInstance();
try {
+ //コマンドライン引数 解析
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse(options, args);
-
final String mextStdFoodCompTableFileName = cmd.getOptionValue("std-food-comp-table");
final String columnsXmlFileName = cmd.getOptionValue("columns");
final String outputXlsxFileName = cmd.getOptionValue("output");
final int lines = Integer.parseInt(cmd.getOptionValue("lines"));
- //コンフィグ読み込み
+ //コンフィグ (列設定) 読み込み
NutritionColumnHolder nch = new NutritionColumnHolder(columnsXmlFileName);
//Book生成
//「栄養価計算」シート生成
- Sheet calcSheet = outputWorkbook.createSheet("栄養価計算");
- outputWorkbook.setSheetOrder("栄養価計算", 0);
- if(cmd.hasOption("set-protect")) {
- calcSheet.protectSheet("");
- }
- calcSheet.setColumnWidth(2, 10240);
- calcSheet.addMergedRegion(new CellRangeAddress(1, 2, 1, 1));
-
CellStylePool csPool = new CellStylePool(outputWorkbook);
-
- //「タイトル」行
- Row titleRow = calcSheet.createRow(1);
- titleRow.createCell(1).setCellValue("食品番号");
- titleRow.createCell(2).setCellValue("食品名");
- titleRow.createCell(3).setCellValue("摂取量");
- int colIndex = COL_INDEX_START;
- for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
- titleRow.createCell(colIndex).setCellValue(aColumn.getDispName());
- colIndex++;
- }
-
- //「単位」行
- Row unitRow = calcSheet.createRow(2);
- unitRow.createCell(2).setCellValue("単位");
- unitRow.createCell(3).setCellValue("g");
- colIndex = COL_INDEX_START;
- for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
- unitRow.createCell(colIndex).setCellValue(aColumn.getUnit());
- colIndex++;
- }
-
- //「栄養計算」行
List<String> usedTableList = new ArrayList<String>();
- int rowIndex = 3;
- for(int i = rowIndex; i < lines + 3; i++,rowIndex++) {
- Row thisRow = calcSheet.createRow(rowIndex);
-
- //「食品名」
- thisRow.createCell(1).setCellStyle(csPool.getCellStyle("00000", false));
- thisRow.createCell(2).setCellFormula("IFERROR(VLOOKUP(B" + (rowIndex + 1) + ",成分表!$B$13:$BL$2500,3,FALSE),\"\")");
- thisRow.createCell(3).setCellStyle(csPool.getCellStyle("", false));
-
- colIndex = COL_INDEX_START;
- for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
- Cell thisCell = thisRow.createCell(colIndex);
- thisCell.setCellStyle(csPool.getCellStyle(aColumn.getFormat()));
-
- if(aColumn.getFormula().length() >= 1) {
- //「計算式」列
- String formula = "(" + aColumn.getFormula() + ")";
- for(String aAlias : nch.getNutritionAliasList()) {
- String cell = new CellReference(rowIndex, 4 + nch.indexOf(aAlias)).formatAsString();
- formula = formula.replaceAll("([^A-Za-z0-9_])" + aAlias + "([^A-Za-z0-9_])", "$1" + cell + "$2");
- }
- //System.out.println(formula);
- thisCell.setCellFormula(formula);
- //thisCell.setCellValue(formula);
-
-
- } else {
- String div100 = aColumn.isUseRawValue() ? "" : "/ 100 * $D" + (rowIndex + 1);
- thisCell.setCellFormula("IFERROR(VLOOKUP($B" + (rowIndex + 1) + "," + aColumn.getTable() + "!$B$13:$BL$2500,MATCH(\"" + aColumn.getName() + "\"," + aColumn.getTable() + "!$B$12:$BL$12,0),FALSE) " + div100 + ",\"\")");
- }
-
- colIndex++;
-
- usedTableList.add(aColumn.getTable());
+ List<String> sheetNameList = new ArrayList<String>();
+
+
+ String[] sheets = cmd.getOptionValues("sheets");
+ if(sheets != null && sheets.length >= 2) {
+ //表が複数
+ for(int si = 0; si < sheets.length - 1; si++) {
+ final String sheetName = sheets[si];
+ generateCalculationSheet(outputWorkbook, sheetName, namedArea, cmd.hasOption("set-protect"), cmd.getOptionValues("addition"), lines, nch, csPool, usedTableList);
+ outputWorkbook.setSheetOrder(sheetName, si);
+ sheetNameList.add(sheetName);
}
-
+ final String sumSheetName = sheets[sheets.length - 1];
+ generateSumSheet(outputWorkbook, sumSheetName, sheetNameList, namedArea, cmd.hasOption("set-protect"), cmd.getOptionValues("addition"), lines, nch, csPool, usedTableList);
+ outputWorkbook.setSheetOrder(sumSheetName, sheets.length - 1);
+
+ }else {
+ //表がひとつ
+ final String sheetName = (sheets != null) ? sheets[0] : "栄養価計算";
+ generateCalculationSheet(outputWorkbook, sheetName, namedArea, cmd.hasOption("set-protect"), cmd.getOptionValues("addition"), lines, nch, csPool, usedTableList);
+ outputWorkbook.setSheetOrder(sheetName, 0);
+ sheetNameList.add(sheetName);
}
-
-
- //摂取量 範囲を記憶
- String intakeArea = new CellReference(3, 3, true, true).formatAsString() + ":" + new CellReference(rowIndex -1, 3, true, true).formatAsString();
- namedAreaMap.put("AREA_INTAKE", intakeArea);
-
-
- //「合計」行
- Row sumRow = calcSheet.createRow(rowIndex);
- sumRow.createCell(1).setCellValue("合計");
- calcSheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 1, 3));
- colIndex = COL_INDEX_START;
- for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
- Cell thisCell = sumRow.createCell(colIndex);
- String sumTargetArea = new CellReference(3, colIndex, true, true).formatAsString() + ":" + new CellReference(rowIndex -1, colIndex, true, true).formatAsString();
-
- //範囲を記憶(alias あれば設定)
- if(aColumn.getAlias().length() > 0) {
- namedAreaMap.put("AREA_" + aColumn.getAlias(), sumTargetArea);
-
- if(aColumn.isUseSum()) {
- String sumArea = new CellReference(rowIndex, colIndex, true, true).formatAsString();
- namedAreaMap.put("SUM_" + aColumn.getAlias(), sumArea);
- //System.out.println("SUM_" + aColumn.getAlias() + " --- " + sumArea);
- }
- }
-
- thisCell.setCellStyle(csPool.getCellStyle(aColumn.getFormat()));
- if(aColumn.isUseSum()) {
- thisCell.setCellFormula("SUM(" + sumTargetArea + ")");
- }
- colIndex++;
- }
-
-
- //「PFCバランス」出力
- if(cmd.hasOption("with-pfc-balance")) {
- rowIndex += 3;
- rowIndex = generatePfcBalance(calcSheet, csPool, rowIndex, namedAreaMap);
- rowIndex += 1;
- rowIndex = generatePfcBalance8(calcSheet, csPool, rowIndex, namedAreaMap);
- }
-
- //「食品群別摂取量」出力
- if(cmd.hasOption("with-group-sum")) {
- rowIndex += 3;
- rowIndex = generateGroupSum(calcSheet, csPool, rowIndex, namedAreaMap);
- }
-
-
+
+
//未使用表シート削除
for(int si = outputWorkbook.getNumberOfSheets() - 1 ; si >= 1 ; si--) {
String sheetName = outputWorkbook.getSheetName(si);
outputWorkbook.removeSheetAt(si);
}
}
-
+
//ブック出力
FileOutputStream outputXlsxFile = new FileOutputStream(outputXlsxFileName);
outputWorkbook.setActiveSheet(0);
- calcSheet.setForceFormulaRecalculation(true);
+
outputWorkbook.setSelectedTab(0);
outputWorkbook.write(outputXlsxFile);
outputWorkbook.close();
- //PFCバランス
- private static int generatePfcBalance(Sheet calcSheet, CellStylePool csPool, int rowIndex, Map<String,String> _namedAreaMap) {
- Row pfbBalanceRow1 = calcSheet.createRow(rowIndex);
- pfbBalanceRow1.createCell(1).setCellValue("PFCバランス (%) 七訂の方法で計算したエネルギー量で計算");
- calcSheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 1, 2));
- pfbBalanceRow1.createCell(3).setCellValue("P");
- pfbBalanceRow1.createCell(4).setCellValue("F");
- pfbBalanceRow1.createCell(5).setCellValue("C");
- final String sumKiloCalorieCell = _namedAreaMap.get("SUM_KCAL");
- rowIndex++;
- Row pfbBalanceRow2 = calcSheet.createRow(rowIndex);
- Cell pCell = pfbBalanceRow2.createCell(3);
- pCell.setCellStyle(csPool.getCellStyle("0"));
- pCell.setCellFormula("ROUND(" + _namedAreaMap.get("SUM_P") + "*4*100/" + sumKiloCalorieCell + ",0)");
- Cell fCell = pfbBalanceRow2.createCell(4);
- fCell.setCellStyle(csPool.getCellStyle("0"));
- fCell.setCellFormula("ROUND(" + _namedAreaMap.get("SUM_F") + "*9*100/" + sumKiloCalorieCell + ",0)");
- Cell cCell = pfbBalanceRow2.createCell(5);
- cCell.setCellStyle(csPool.getCellStyle("0"));
- cCell.setCellFormula("100 - (" + new CellReference(cCell.getRowIndex(), 3).formatAsString() + " + "
- + new CellReference(cCell.getRowIndex(), 4).formatAsString() + ")");
- return rowIndex;
- }
+ //「栄養価計算」シート生成
+ private static void generateCalculationSheet(Workbook book, String sheetName, NamedAreaStore namedArea, boolean setProtect,
+ String[] additionOptionValues, final int lines,
+ NutritionColumnHolder nch, CellStylePool csPool, List<String> usedTableList) {
+
+
+ Sheet calcSheet = book.createSheet(sheetName);
+
+ if(setProtect) {
+ calcSheet.protectSheet("");
+ }
+ calcSheet.setColumnWidth(COL_INDEX_START -2, 10240); //C「食品名」列
+ calcSheet.addMergedRegion(new CellRangeAddress(ROW_INDEX_START -2, ROW_INDEX_START -1,
+ COL_INDEX_START -3, COL_INDEX_START -3)); //B2:B3「食品番号」セル
+
+
+ //「タイトル」行
+ Row titleRow = calcSheet.createRow(ROW_INDEX_START -2);
+ titleRow.createCell(COL_INDEX_START -3).setCellValue("食品番号");
+ titleRow.createCell(COL_INDEX_START -2).setCellValue("食品名");
+ titleRow.createCell(COL_INDEX_START -1).setCellValue("摂取量");
+ int colIndex = COL_INDEX_START;
+ for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
+ titleRow.createCell(colIndex).setCellValue(aColumn.getDispName());
+ colIndex++;
+ }
+
+ //「単位」行
+ Row unitRow = calcSheet.createRow(ROW_INDEX_START -1);
+ unitRow.createCell(COL_INDEX_START -2).setCellValue("単位");
+ unitRow.createCell(COL_INDEX_START -1).setCellValue("g");
+ colIndex = COL_INDEX_START;
+ for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
+ unitRow.createCell(colIndex).setCellValue(aColumn.getUnit());
+ colIndex++;
+ }
+ //「栄養計算」行
+ int rowIndex = ROW_INDEX_START;
+ for(int i = rowIndex; i < lines + ROW_INDEX_START; i++,rowIndex++) {
+ Row thisRow = calcSheet.createRow(rowIndex);
- //PFCバランス(八訂)
- private static int generatePfcBalance8(Sheet calcSheet, CellStylePool csPool, int rowIndex, Map<String,String> _namedAreaMap) {
- Row pfbBalanceRow1 = calcSheet.createRow(rowIndex);
- pfbBalanceRow1.createCell(1).setCellValue("PFCバランス (%) 八訂のエネルギー量で計算");
- calcSheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 1, 2));
- pfbBalanceRow1.createCell(3).setCellValue("P");
- pfbBalanceRow1.createCell(4).setCellValue("F");
- pfbBalanceRow1.createCell(5).setCellValue("C");
+ //「食品名」
+ thisRow.createCell(COL_INDEX_START -3).setCellStyle(csPool.getCellStyle("00000", false));
+ thisRow.createCell(COL_INDEX_START -2).setCellFormula("IFERROR(VLOOKUP(B" + (rowIndex + 1) +
+ ",成分表!$B$13:$BL$2500,3,FALSE),\"\")");
+ thisRow.createCell(COL_INDEX_START -1).setCellStyle(csPool.getCellStyle("", false));
- final String sumKiloCalorieCell = _namedAreaMap.get("SUM_KCAL");
+ colIndex = COL_INDEX_START;
+ for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
+ Cell thisCell = thisRow.createCell(colIndex);
+ thisCell.setCellStyle(csPool.getCellStyle(aColumn.getFormat()));
- rowIndex++;
- Row pfbBalanceRow2 = calcSheet.createRow(rowIndex);
- Cell pCell = pfbBalanceRow2.createCell(3);
- pCell.setCellStyle(csPool.getCellStyle("0"));
- pCell.setCellFormula("ROUND(" + _namedAreaMap.get("SUM_P_ENG") + "*4*100/" + sumKiloCalorieCell + ",0)");
+ if(aColumn.getFormula().length() >= 1) {
+ //「計算式」列
+ String formula = aColumn.getFormula();
+ for(String aAlias : nch.getNutritionAliasList()) {
+ formula = replaceFormula(formula, aAlias, rowIndex, COL_INDEX_START + nch.indexOf(aAlias));
+ }
+ thisCell.setCellFormula(formula);
- Cell fCell = pfbBalanceRow2.createCell(4);
- fCell.setCellStyle(csPool.getCellStyle("0"));
- fCell.setCellFormula("ROUND(" + _namedAreaMap.get("SUM_F_ENG") + "*9*100/" + sumKiloCalorieCell + ",0)");
- Cell cCell = pfbBalanceRow2.createCell(5);
- cCell.setCellStyle(csPool.getCellStyle("0"));
- cCell.setCellFormula("100 - (" + new CellReference(cCell.getRowIndex(), 3).formatAsString() + " + "
- + new CellReference(cCell.getRowIndex(), 4).formatAsString() + ")");
+ } else {
+ //通常の栄養素の列
+ String div100 = aColumn.isUseRawValue() ? "" : "/ 100 * $D" + (rowIndex + 1);
+ thisCell.setCellFormula("IFERROR(VLOOKUP($B" + (rowIndex + 1) + "," + aColumn.getTable() +
+ "!$B$13:$BL$2500,MATCH(\"" + aColumn.getName() + "\"," +
+ aColumn.getTable() + "!$B$12:$BL$12,0),FALSE) " + div100 + ",\"\")");
+ }
+
+ colIndex++;
+
+ usedTableList.add(aColumn.getTable());
+ usedTableList.add(sheetName);
+ }
+
+ }
+
+
+ //摂取量 範囲を記憶
+ namedArea.save("AREA_INTAKE", ROW_INDEX_START, COL_INDEX_START -1, rowIndex -1, COL_INDEX_START -1);
+
+
+ //「合計」行
+ Row sumRow = calcSheet.createRow(rowIndex);
+ sumRow.createCell(COL_INDEX_START -3).setCellValue("合計");
+ calcSheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, COL_INDEX_START -3, COL_INDEX_START -2));
+
+ //「摂取量」合計
+ Cell intakeSumCell = sumRow.createCell(COL_INDEX_START -1);
+ intakeSumCell.setCellFormula("SUM(" + namedArea.load("AREA_INTAKE") + ")");
+ namedArea.save("SUM_INTAKE", intakeSumCell);
+
+ colIndex = COL_INDEX_START;
+ for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
+ Cell thisCell = sumRow.createCell(colIndex);
+
+ //範囲を記憶
+ String areaName = aColumn.getAlias().length() >= 1 ? ("AREA_" + aColumn.getAlias()) : ("AREAID_" + aColumn.getName());
+ namedArea.save(areaName, ROW_INDEX_START, colIndex, rowIndex -1, colIndex);
+
+ if(aColumn.isUseSum()) {
+ String sumName = aColumn.getAlias().length() >= 1 ? ("SUM_" + aColumn.getAlias()) : ("SUMID_" + aColumn.getName());
+ namedArea.save(sumName, thisCell);
+ }
+
+ thisCell.setCellStyle(csPool.getCellStyle(aColumn.getFormat()));
+ if(aColumn.isUseSum()) {
+ thisCell.setCellFormula("SUM(" +
+ NamedAreaStore.getAreaString(ROW_INDEX_START, colIndex, rowIndex -1, colIndex) +
+ ")");
+ }
+ colIndex++;
+ }
+
+
+ //「付加行」出力
+ if(additionOptionValues != null) {
+ for(String aAdditionFileName : additionOptionValues) {
+ rowIndex += 2;
+ rowIndex = generateAddition(aAdditionFileName, calcSheet, null, csPool, rowIndex, namedArea);
+ }
+ }
+
+ calcSheet.setForceFormulaRecalculation(true);
- return rowIndex;
}
- //群別摂取量
- private static int generateGroupSum(Sheet calcSheet, CellStylePool csPool, int rowIndex, Map<String,String> _namedAreaMap) {
+
+
+
+ //集計用シート生成
+ private static void generateSumSheet(Workbook book, String sheetName, List<String> sheetNameList, NamedAreaStore namedArea, boolean setProtect,
+ String[] additionOptionValues, final int lines,
+ NutritionColumnHolder nch, CellStylePool csPool, List<String> usedTableList) {
- List<String> groupName = Arrays.asList("0", "穀類", "いも及びでん粉類", "砂糖及び甘味類", "豆類",
- "種実類", "野菜類", "果実類", "きのこ類", "藻類", "魚介類", "肉類", "卵類", "乳類",
- "油脂類", "菓子類", "し好飲料類", "調味料及び香辛料類", "調理加工食品類");
+ usedTableList.add(sheetName);
+ Sheet sheet = book.createSheet(sheetName);
+ if(setProtect) {
+ sheet.protectSheet("");
+ }
+
+ //「表」
+ sheet.setColumnWidth(COL_INDEX_START -2, 10240); //C
+ sheet.addMergedRegion(new CellRangeAddress(ROW_INDEX_START -2, ROW_INDEX_START -1,
+ COL_INDEX_START -3, COL_INDEX_START -2)); //B2:C3「表」セル
+
+
+ //「タイトル」行
+ Row titleRow = sheet.createRow(ROW_INDEX_START -2);
+ titleRow.createCell(COL_INDEX_START -3).setCellValue("表");
+ titleRow.createCell(COL_INDEX_START -1).setCellValue("摂取量");
+ int colIndex = COL_INDEX_START;
+ for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
+ titleRow.createCell(colIndex).setCellValue(aColumn.getDispName());
+ colIndex++;
+ }
+ //「単位」行
+ Row unitRow = sheet.createRow(ROW_INDEX_START -1);
+ unitRow.createCell(COL_INDEX_START -2).setCellValue("単位");
+ unitRow.createCell(COL_INDEX_START -1).setCellValue("g");
+ colIndex = COL_INDEX_START;
+ for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
+ unitRow.createCell(colIndex).setCellValue(aColumn.getUnit());
+ colIndex++;
+ }
- Row groupRow = calcSheet.createRow(rowIndex);
- groupRow.createCell(1).setCellValue("食品群");
- groupRow.createCell(3).setCellValue("摂取量(g)");
- rowIndex++;
+ //表ごとの小計
+ int rowIndex = ROW_INDEX_START;
+ for(String aSheetName : sheetNameList) {
+ Row thisRow = sheet.createRow(rowIndex);
+
+ sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex,
+ COL_INDEX_START -3, COL_INDEX_START -2)); //B:C「表」セル
+
+ //「表」列
+ thisRow.createCell(COL_INDEX_START -3).setCellValue(aSheetName);
+
+ //「摂取量」列
+ thisRow.createCell(COL_INDEX_START -1).setCellFormula(aSheetName + "!" + namedArea.load("SUM_INTAKE"));
+
+
+ //「表ごとの小計」列
+ colIndex = COL_INDEX_START;
+ for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
+ Cell thisCell = thisRow.createCell(colIndex);
+ thisCell.setCellStyle(csPool.getCellStyle(aColumn.getFormat()));
+ if(aColumn.isUseSum()) {
+ String sumName = aColumn.getAlias().length() >= 1 ? ("SUM_" + aColumn.getAlias()) : ("SUMID_" + aColumn.getName());
+ String formula = aSheetName + "!" + namedArea.load(sumName);
+ thisCell.setCellFormula(formula);
+ }
+
+ colIndex++;
- for(int i = 1; i <= 18; i++,rowIndex++) {
- Row thisRow = calcSheet.createRow(rowIndex);
- thisRow.createCell(1).setCellValue(i);
- thisRow.createCell(2).setCellValue(groupName.get(i));
- Cell cCell = thisRow.createCell(3);
- cCell.setCellStyle(csPool.getCellStyle(""));
- //cCell.setCellFormula("SUMIF(AREA_GROUP, " + i + ", AREA_INTAKE)");
- cCell.setCellFormula("SUMIF(" + _namedAreaMap.get("AREA_GROUP") + ", " + i + ", " + _namedAreaMap.get("AREA_INTAKE") + ")");
-
- if(i == 6) {
- rowIndex++;
- thisRow = calcSheet.createRow(rowIndex);
- thisRow.createCell(2).setCellValue("うち 緑黄色野菜");
- Cell bcvCell = thisRow.createCell(3);
- bcvCell.setCellStyle(csPool.getCellStyle("0"));
- //bcvCell.setCellFormula("SUMIF(AREA_BRIGHT_COLORED_VEGETABLE, 1, AREA_INTAKE)");
- bcvCell.setCellFormula("SUMIF(" + _namedAreaMap.get("AREA_BRIGHT_COLORED_VEGETABLE") + ", 1, " + _namedAreaMap.get("AREA_INTAKE") + ")");
}
+ rowIndex++;
+ }
+
+
+ //摂取量 範囲を記憶
+ namedArea.save("AREA_INTAKE", ROW_INDEX_START, COL_INDEX_START -1, rowIndex -1, COL_INDEX_START -1);
+
+ //「合計」行
+ Row sumRow = sheet.createRow(rowIndex);
+ sumRow.createCell(COL_INDEX_START -3).setCellValue("合計");
+ sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, COL_INDEX_START -3, COL_INDEX_START -2));
+
+ Cell intakeSumCell = sumRow.createCell(COL_INDEX_START -1);
+ intakeSumCell.setCellFormula("SUM(" + namedArea.load("AREA_INTAKE") + ")");
+
+ colIndex = COL_INDEX_START;
+ for(NutritionColumn aColumn : nch.getNutritionColumnList()) {
+ Cell thisCell = sumRow.createCell(colIndex);
+
+ //範囲を記憶
+ String areaName = aColumn.getAlias().length() >= 1 ? ("AREA_" + aColumn.getAlias()) : ("AREAID_" + aColumn.getName());
+ namedArea.save(areaName, ROW_INDEX_START, colIndex, rowIndex -1, colIndex);
+
+ if(aColumn.isUseSum()) {
+ String sumName = aColumn.getAlias().length() >= 1 ? ("SUM_" + aColumn.getAlias()) : ("SUMID_" + aColumn.getName());
+ namedArea.save(sumName, thisCell);
+ }
+
+
+ thisCell.setCellStyle(csPool.getCellStyle(aColumn.getFormat()));
+ if(aColumn.isUseSum()) {
+ thisCell.setCellFormula("SUM(" +
+ NamedAreaStore.getAreaString(ROW_INDEX_START, colIndex, rowIndex -1, colIndex) +
+ ")");
+ }
+ colIndex++;
}
- return rowIndex;
+
+ //「付加行」出力
+ if(additionOptionValues != null) {
+ for(String aAdditionFileName : additionOptionValues) {
+ rowIndex += 2;
+ rowIndex = generateAddition(aAdditionFileName, sheet, sheetNameList, csPool, rowIndex, namedArea);
+ }
+ }
+
+ sheet.setForceFormulaRecalculation(true);
+
}
+
+
+
+
+ //「付加行」生成
+ private static int generateAddition(String fileName, Sheet calcSheet, List<String> sheetNameList, CellStylePool csPool, int rowIndex,
+ NamedAreaStore namedArea) {
+
+ AdditionConfig ac = AdditionUtil.additionFileReader(new File(fileName));
+ int cellCounter = 0;
+ for(AcRow acRow : ac.getRows()) { //行ごとのループ
+ Row thisRow = calcSheet.createRow(rowIndex);
+ int colIndex = 0;
+
+ for(AcCell acCell : acRow.getCells()) { //セルごとのループ
+ Cell thisCell = thisRow.createCell(colIndex);
+
+ cellCounter++;
+ if(sheetNameList == null) {
+ String areaName = "ADDITION_" + fileName + "_" + cellCounter;
+ namedArea.save(areaName, rowIndex, colIndex);
+ }
+
+ //alias 「付加行」内の別名定義(制約:右方・下方のセルからしか参照できない)
+ if(acCell.getAlias() != null) {
+ namedArea.save(acCell.getAlias(), rowIndex, colIndex);
+ }
+
+ //formula 計算式
+ if(acCell.getFormula() != null){
+ String formula = acCell.getFormula();
+
+ if(sheetNameList != null && formula.indexOf("AREA_") != -1) {
+ //集計シート && 名前付き範囲 AREA_ が対象に含まれる
+ List<String> sumTarget = new ArrayList<String>();
+ for(String aSheetName : sheetNameList) {
+ String areaName = "ADDITION_" + fileName + "_" + cellCounter;
+ sumTarget.add(aSheetName + "!" + namedArea.load(areaName));
+ }
+ formula = "SUM(" + StringUtils.join(sumTarget, ",") + ")";
+
+ }else {
+ //それ以外
+ for(Entry<String, String> keyValue : namedArea.entrySet()) {
+ String k = keyValue.getKey();
+ String v = keyValue.getValue();
+
+ formula = replaceFormula(formula, k, v);
+ }
+ }
+ thisCell.setCellFormula(formula);
+
+ //value そのままの値
+ } else if(acCell.getValue() != null) {
+ thisCell.setCellValue(acCell.getValue());
+
+ //formula でも value でもない
+ } else {
+ //
+ }
+
+
+ colIndex++;
+ } //セルごとのループ
+
+ rowIndex++;
+ } //行ごとのループ
+
+ return rowIndex - 1;
+ }
+ //計算式中の文字列(名前付き範囲)置換
+ private static String replaceFormula(String formula, String target, String replacement) {
+ formula = "<" + formula + ">";
+ replacement = Matcher.quoteReplacement(replacement);
+ formula = formula.replaceAll("([^A-Za-z0-9_])" + target + "([^A-Za-z0-9_])", "$1" + replacement + "$2");
+ formula = formula.replaceAll("^<", "");
+ formula = formula.replaceAll(">$", "");
+ return formula;
+ }
+
+ //計算式中の 文字列(名前付き範囲)→セル座標 置換
+ private static String replaceFormula(String formula, String target, int cellRow, int cellCol) {
+ return replaceFormula(formula, target, new CellReference(cellRow, cellCol).formatAsString());
+ }
+