読者です 読者をやめる 読者になる 読者になる

Apache POI Excel入力規則の読み込み(1)

Apache POI で Excel の入力規則によるプルダウンの情報を読み取る場合、同じシート内のセルで入力規則の値を格納していないと読み取れない。

f:id:posturan:20160521212235j:plain

f:id:posturan:20160521212317j:plain

このように同じシート内にある入力規則の情報を参照するコードサンプルを書いてみた。
(ただし、このサンプルは縦方向リストのみ)

try(InputStream is = new FileInputStream("template.xlsx");){
	XSSFWorkbook book = new XSSFWorkbook(is);
	XSSFSheet sheet = book.getSheetAt(0);
	/* List<XSSFDataValidation> を取得して展開  */
	sheet.getDataValidations().stream().forEach(e->{
		// CellRangeAddress[] を取得して入力規則適用されてるセルのリファレンスを参照
		Arrays.stream(e.getRegions().getCellRangeAddresses()).forEach(r->{
			String region_start_cellrefer = sheet.getRow(r.getFirstRow()).getCell(r.getFirstColumn()).getReference();
			String region_end_cellrefer = sheet.getRow(r.getLastRow()).getCell(r.getLastColumn()).getReference();
			System.out.println("対象セル:" + region_start_cellrefer + " - " + region_end_cellrefer );
		});
		// 入力時のタイトルとメッセージ
		System.out.println("title = "+ e.getPromptBoxTitle() );
		System.out.println("text  = "+ e.getPromptBoxText() );
		// 入力規則 DataValidationConstraint を取得して、入力規則リスト格納領域を getExplicitListValues() で取得して参照
		Arrays.stream(e.getValidationConstraint().getExplicitListValues()).forEach(p->{
			System.out.println("Excel の 入力規則リスト値格納セル:" +p);
			String[] ary = p.replaceAll("\\$", "").split(":");
			int startRow = Integer.parseInt(ary[0].replaceAll("[A-Z]+", "")) - 1;
			int endRow   = Integer.parseInt(ary[1].replaceAll("[A-Z]+", "")) - 1;
			int startCol = CellReference.convertColStringToIndex(ary[0].replaceAll("[0-9]+", ""));
			int endCol   = CellReference.convertColStringToIndex(ary[1].replaceAll("[0-9]+", ""));
			if (startRow==endRow){
				IntStream.rangeClosed(startCol, endCol).forEach(i->{
					XSSFCell cell = sheet.getRow(startRow).getCell(i);
					if (cell.getCellType()==Cell.CELL_TYPE_NUMERIC){
						Integer data = new Double(cell.getNumericCellValue()).intValue();
						System.out.println(data);
					}else if(cell.getCellType()==Cell.CELL_TYPE_STRING){
						String data = cell.getStringCellValue();
						System.out.println(data);
					}
				});
			}else{
				IntStream.rangeClosed(startRow, endRow).forEach(i->{
					XSSFCell cell = sheet.getRow(i).getCell(startCol);
					if (cell.getCellType()==Cell.CELL_TYPE_NUMERIC){
						Integer data = new Double(cell.getNumericCellValue()).intValue();
						System.out.println(data);
					}else if(cell.getCellType()==Cell.CELL_TYPE_STRING){
						String data = cell.getStringCellValue();
						System.out.println(data);
					}
				});
			}
		});
		System.out.println("------------------------------------");
	});
}catch(Exception e){
	e.printStackTrace();
}

結果としては、以下のような標準出力結果が得られる。

対象セル:D5 - D5
title = タイトル1
text = メッセージ1
Excel の 入力規則リスト値格納セル:$L$2:$L$6
A
B
C
D
E
'--------------------------------'
対象セル:E5 - E5
対象セル:G5 - G5
title = タイトル2
text = メッセージ2
Excel の 入力規則リスト値格納セル:$M$2:$M$6
100
200
300
400
500
'--------------------------------'