・緑黄色野菜 修正
[nucalgen] / src / main / java / jp / satomichan / nucalgen / Nucalgen.java
1 package jp.satomichan.nucalgen;
2
3 import java.io.FileInputStream;
4 import java.io.FileOutputStream;
5 import java.util.Arrays;
6 import java.util.List;
7
8 import org.apache.commons.cli.CommandLine;
9 import org.apache.commons.cli.CommandLineParser;
10 import org.apache.commons.cli.DefaultParser;
11 import org.apache.commons.cli.Option;
12 import org.apache.commons.cli.Options;
13 import org.apache.commons.configuration.XMLConfiguration;
14 import org.apache.poi.ss.usermodel.Cell;
15 import org.apache.poi.ss.usermodel.Row;
16 import org.apache.poi.ss.usermodel.Sheet;
17 import org.apache.poi.ss.usermodel.Workbook;
18 import org.apache.poi.ss.usermodel.WorkbookFactory;
19 import org.apache.poi.ss.util.CellRangeAddress;
20 import org.apache.poi.ss.util.CellReference;
21 import org.apache.poi.xssf.usermodel.XSSFName;
22
23 public class Nucalgen {
24
25         public static void main(String[] args) {
26                 //コマンドライン・オプション読み込み
27                 Options options = new Options();
28                 options.addOption(Option.builder("s").required().hasArg().longOpt("std-food-comp-table").build());
29                 options.addOption(Option.builder("c").required().hasArg().longOpt("columns").build());
30                 options.addOption(Option.builder("o").required().hasArg().longOpt("output").build());
31                 options.addOption(Option.builder("l").required().hasArg().longOpt("lines").build());
32                 options.addOption(Option.builder("p").longOpt("use-processed-table").build());
33                 options.addOption(Option.builder("pfc").longOpt("with-pfc-balance").build());
34                 options.addOption(Option.builder("groupsum").longOpt("with-group-sum").build());
35                 options.addOption(Option.builder("bright").hasArg().longOpt("bright-colored-vegetables-list").build());
36                 options.addOption(Option.builder("protect").longOpt("set-protect").build());
37                 options.addOption(Option.builder("r").longOpt("-use-processed-table").build());
38
39                 try {
40
41                         CommandLineParser parser = new DefaultParser();
42                         CommandLine cmd = parser.parse(options, args);
43
44                         final String mextStdFoodCompTableFileName = cmd.getOptionValue("std-food-comp-table");
45                         final String columnsXmlFileName = cmd.getOptionValue("columns");
46                         final String outputXlsxFileName = cmd.getOptionValue("output");
47                         final int lines = Integer.parseInt(cmd.getOptionValue("lines"));
48
49                         //コンフィグ読み込み
50                         XMLConfiguration config = new XMLConfiguration(columnsXmlFileName);
51                         NutritionColumnHolder nc = new NutritionColumnHolder(config);
52
53                         //Book生成
54                         Workbook outputWorkbook = WorkbookFactory.create(new FileInputStream(mextStdFoodCompTableFileName));
55
56                         if(cmd.hasOption("use-processed-table") == false) {
57                                 //成分表 変換
58                                 MextStdFoodCompTable stdCompTable = new MextStdFoodCompTable(cmd.getOptionValue("bright-colored-vegetables-list"));
59                                 stdCompTable.processInto(outputWorkbook);
60                         }
61
62
63                         //「栄養価計算」シート生成
64                         Sheet calcSheet = outputWorkbook.createSheet("栄養価計算");
65                         outputWorkbook.setSheetOrder("栄養価計算", 0);
66                         if(cmd.hasOption("set-protect")) {
67                                 calcSheet.protectSheet("");
68                         }
69                         calcSheet.setColumnWidth(2, 10240);
70                         calcSheet.addMergedRegion(new CellRangeAddress(1, 2, 1, 1));
71
72                         CellStylePool csPool = new CellStylePool(outputWorkbook);
73
74                         //「タイトル」行
75                         Row titleRow = calcSheet.createRow(1);
76                         titleRow.createCell(1).setCellValue("食品番号");
77                         titleRow.createCell(2).setCellValue("食品名");
78                         titleRow.createCell(3).setCellValue("摂取量");
79                         int colIndex = 4;
80                         for(NutritionColumn aColumn : nc.getNutritionColumnList()) {
81                                 titleRow.createCell(colIndex).setCellValue(aColumn.getDispName());
82                                 colIndex++;
83                         }
84
85                         //「単位」行
86                         Row unitRow = calcSheet.createRow(2);
87                         unitRow.createCell(2).setCellValue("単位");
88                         unitRow.createCell(3).setCellValue("g");
89                         colIndex = 4;
90                         for(NutritionColumn aColumn : nc.getNutritionColumnList()) {
91                                 unitRow.createCell(colIndex).setCellValue(aColumn.getUnit());
92                                 colIndex++;
93                         }
94
95                         //「栄養計算」行
96                         int rowIndex = 3;
97                         for(int i = rowIndex; i < lines + 3; i++,rowIndex++) {
98                                 Row thisRow = calcSheet.createRow(rowIndex);
99
100                                 thisRow.createCell(1).setCellStyle(csPool.getCellStyle("00000", false));
101                                 thisRow.createCell(2).setCellFormula("IFERROR(VLOOKUP(B" + (rowIndex + 1) + ",成分表!$B$12:$BL$2500,3,FALSE),\"\")");
102                                 thisRow.createCell(3).setCellStyle(csPool.getCellStyle("", false));
103
104                                 colIndex = 4;
105                                 for(NutritionColumn aColumn : nc.getNutritionColumnList()) {
106                                         Cell thisCell = thisRow.createCell(colIndex);
107                                         thisCell.setCellStyle(csPool.getCellStyle(aColumn.getFormat()));
108
109                                         String div100 = aColumn.isUseRawValue() ? "" :  "/ 100 * $D" + (rowIndex + 1);
110
111                                         thisCell.setCellFormula("IFERROR(VLOOKUP($B" + (rowIndex + 1) + "," + aColumn.getTable() + "!$B$12:$BL$2500,MATCH(\"" + aColumn.getName() + "\"," + aColumn.getTable() + "!$B$11:$BL$11,0),FALSE) " + div100 + ",\"\")");
112                                         colIndex++;
113                                 }
114
115                         }
116
117
118                         //摂取量 名前付き範囲
119                         String intakeArea = new CellReference(calcSheet.getSheetName(), 3, 3, true, true).formatAsString() + ":" + new CellReference(calcSheet.getSheetName(), rowIndex -1, 3, true, true).formatAsString();
120                         XSSFName intakeNamedRangeArea = (XSSFName) outputWorkbook.createName();
121                         intakeNamedRangeArea.setNameName("AREA_INTAKE");
122                         intakeNamedRangeArea.setRefersToFormula(intakeArea);
123
124
125                         //「合計」行
126                         Row sumRow = calcSheet.createRow(rowIndex);
127                         sumRow.createCell(1).setCellValue("合計");
128                         calcSheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 1, 3));
129                         colIndex = 4;
130                         for(NutritionColumn aColumn : nc.getNutritionColumnList()) {
131                                 Cell thisCell = sumRow.createCell(colIndex);
132                                 String sumArea = new CellReference(calcSheet.getSheetName(), 3, colIndex, true, true).formatAsString() + ":" + new CellReference(calcSheet.getSheetName(), rowIndex -1, colIndex, true, true).formatAsString();
133
134                                 //名前付き範囲(alias あれば設定)
135                                 if(aColumn.getAlias().length() > 0) {
136                                         XSSFName namedRangeArea = (XSSFName) outputWorkbook.createName();
137                                         namedRangeArea.setNameName("AREA_" + aColumn.getAlias());
138                                         namedRangeArea.setRefersToFormula(sumArea);
139
140                                         if(aColumn.isUseSum()) {
141                                                 XSSFName namedRangeSum = (XSSFName) outputWorkbook.createName();
142                                                 namedRangeSum.setNameName("SUM_" + aColumn.getAlias());
143                                                 namedRangeSum.setRefersToFormula(new CellReference(calcSheet.getSheetName(), rowIndex, colIndex, true, true).formatAsString());
144                                         }
145                                 }
146
147                                 thisCell.setCellStyle(csPool.getCellStyle(aColumn.getFormat()));
148                                 if(aColumn.isUseSum()) {
149                                         thisCell.setCellFormula("SUM(" + sumArea + ")");
150                                 }
151                                 colIndex++;
152                         }
153
154
155                         //「PFCバランス」出力
156                         if(cmd.hasOption("with-pfc-balance")) {
157                                 rowIndex += 3;
158                                 rowIndex = generatePfcBalance(calcSheet, csPool, rowIndex);
159                         }
160
161                         //「食品群別摂取量」出力
162                         if(cmd.hasOption("with-group-sum")) {
163                                 rowIndex += 3;
164                                 rowIndex = generateGroupSum(calcSheet, csPool, rowIndex);
165                         }
166
167                         //ブック出力
168                         FileOutputStream outputXlsxFile = new FileOutputStream(outputXlsxFileName);
169                         outputWorkbook.setActiveSheet(0);
170                         calcSheet.setForceFormulaRecalculation(true);
171                         outputWorkbook.setSelectedTab(0);
172                         outputWorkbook.write(outputXlsxFile);
173                         outputWorkbook.close();
174
175                 } catch (Exception e) {
176                         // TODO 自動生成された catch ブロック
177                         e.printStackTrace();
178                 }
179         }
180
181
182
183         //PFCバランス
184         private static int generatePfcBalance(Sheet calcSheet, CellStylePool csPool, int rowIndex) {
185                 Row pfbBalanceRow1 = calcSheet.createRow(rowIndex);
186                 pfbBalanceRow1.createCell(1).setCellValue("PFCバランス (%)");
187                 calcSheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 1, 2));
188                 pfbBalanceRow1.createCell(3).setCellValue("P");
189                 pfbBalanceRow1.createCell(4).setCellValue("F");
190                 pfbBalanceRow1.createCell(5).setCellValue("C");
191
192                 rowIndex++;
193                 Row pfbBalanceRow2 = calcSheet.createRow(rowIndex);
194                 Cell pCell = pfbBalanceRow2.createCell(3);
195                 pCell.setCellStyle(csPool.getCellStyle("0"));
196                 pCell.setCellFormula("SUM_P*4*100/(SUM_P*4+SUM_F*9+SUM_C*4)");
197                 Cell fCell = pfbBalanceRow2.createCell(4);
198                 fCell.setCellStyle(csPool.getCellStyle("0"));
199                 fCell.setCellFormula("SUM_F*9*100/(SUM_P*4+SUM_F*9+SUM_C*4)");
200                 Cell cCell = pfbBalanceRow2.createCell(5);
201                 cCell.setCellStyle(csPool.getCellStyle("0"));
202                 cCell.setCellFormula("SUM_C*4*100/(SUM_P*4+SUM_F*9+SUM_C*4)");
203
204                 return rowIndex;
205         }
206
207
208
209          //群別摂取量
210         private static int generateGroupSum(Sheet calcSheet, CellStylePool csPool, int rowIndex) {
211
212                 List<String> groupName = Arrays.asList("0", "穀類", "いも及びでん粉類", "砂糖及び甘味類", "豆類",
213                                 "種実類", "野菜類", "果実類", "きのこ類", "藻類", "魚介類", "肉類", "卵類", "乳類",
214                                 "油脂類", "菓子類", "し好飲料類", "調味料及び香辛料類", "調理加工食品類");
215
216                 Row groupRow = calcSheet.createRow(rowIndex);
217                 groupRow.createCell(1).setCellValue("食品群");
218                 groupRow.createCell(3).setCellValue("摂取量(g)");
219                 rowIndex++;
220
221                 for(int i = 1; i <= 18; i++,rowIndex++) {
222                         Row thisRow = calcSheet.createRow(rowIndex);
223                         thisRow.createCell(1).setCellValue(i);
224                         thisRow.createCell(2).setCellValue(groupName.get(i));
225                         Cell cCell = thisRow.createCell(3);
226                         cCell.setCellStyle(csPool.getCellStyle(""));
227                         cCell.setCellFormula("SUMIF(AREA_GROUP, " + i + ", AREA_INTAKE)");
228
229                         if(i == 6) {
230                                 rowIndex++;
231                                 thisRow = calcSheet.createRow(rowIndex);
232                                 thisRow.createCell(2).setCellValue("うち 緑黄色野菜");
233                                 Cell bcvCell = thisRow.createCell(3);
234                                 bcvCell.setCellStyle(csPool.getCellStyle("0"));
235                                 bcvCell.setCellFormula("SUMIF(AREA_BRIGHT_COLORED_VEGETABLE, 1, AREA_INTAKE)");
236
237                         }
238
239
240                 }
241
242                 return rowIndex;
243         }
244
245
246
247
248
249
250
251
252
253
254 }