- PR -

POIでEXCELファイルを出力し、そのファイルをPOIで読み込んだとき

投稿者投稿内容
Java人
ベテラン
会議室デビュー日: 2005/06/24
投稿数: 94
投稿日時: 2005-10-27 18:09
以下の事例を経験された方がいらっしゃいましたら、情報を頂けないでしょうか?
[事例]
 POIを使用してEXCELファイルを出力してそのファイルをPOIで読み込んだ場合、
 各行の最終カラムが欠落して読み込まれてしまう。
 なお、そのEXCELファイルを手で加工すると最終カラムまで読み込む。

このような現象が発生して困っております。
経験された方がいらっしゃいましたらお願いいたします。
Desmo
大ベテラン
会議室デビュー日: 2004/03/24
投稿数: 149
投稿日時: 2005-10-27 18:47
もしも簡単なサンプルコードがあるなら、こちらでも試して見ることは可能ですが・・・
(それで解決できるかどうかわかりませんが)
Java人
ベテラン
会議室デビュー日: 2005/06/24
投稿数: 94
投稿日時: 2005-10-27 19:06
ちょっと長くなりますが、ロジックを抜粋します。
申し訳ないですがよろしくお願いします。

EXCELへの出力部分が以下ようなロジックになっております。
----------------------------------------------------------------------
private void makeExcelDataFile() throws Exception {
HSSFWorkbook workbook = new ExcelWorkbook();
FileOutputStream fileOut = null;
int rowCnt = 0;

// シートのインスタンスを生成する
HSSFSheet sheet = workbook.createSheet();

// スタイルのインスタンスを生成する
HSSFCellStyle style = workbook.createCellStyle();
this.setSheet(workbook, sheet, style, "test");

try {
// 入力ファイル名にXLSがなければ付ける
if ((this.fileName.indexOf("xls") < 0) &&
(this.fileName.indexOf("csv") < 0)) {
this.setFileName(this.fileName + ".xls");
}

// ファイルが存在すれば削除する
File file = new File(this.fileName);
if (file.exists()) {
file.delete();
}

// ファイルをオープンする
fileOut = new FileOutputStream(this.fileName);

//----------------------
// ヘッダ部を書き込み
//----------------------
// 書き込む行を取得する
HSSFRow rowHeader = sheet.createRow((short)rowCnt++);

// 書き込みを行う
this.setCell(rowHeader, style, 0, "担当者名1");
this.setCell(rowHeader, style, 1, "担当者名2");
this.setCell(rowHeader, style, 2, "入金約束日");
this.setCell(rowHeader, style, 3, "お客様番号");
this.setCell(rowHeader, style, 4, "氏名");
this.setCell(rowHeader, style, 5, "経過記録・内容");
this.setCell(rowHeader, style, 6, "最新収入日");
this.setCell(rowHeader, style, 7, "調定年月回");
this.setCell(rowHeader, style, 8, "納入金額");

// ファイルへ出力する
workbook.write(fileOut);

} catch (Throwable e) {
throw new Exception(e);

} finally {
if (fileOut != null) {
fileOut.close();
}
}
}

private void setCell(HSSFRow row, HSSFCellStyle style, int col, String value) {
HSSFCell cell = row.createCell((short)col);

//日本語化
cell.setEncoding(HSSFCell.ENCODING_UTF_16);

//スタイルのセット
cell.setCellStyle(style);

//セル値のセット
cell.setCellValue(value);
}
----------------------------------------------------------------------

EXCELの読込部分が以下ようなロジックになっております。
----------------------------------------------------------------------
private void read(String fileName, int sheetNo) throws IOException {
try {
// EXCELファイルを読み込む
FileInputStream inStream = new FileInputStream(fileName);
HSSFWorkbook workBook = new ExcelWorkbook(inStream);

// 指定されたシート番号が存在しない場合
if (sheetNo >= workBook.getNumberOfSheets()) {
throw new IOException("指定されたシート番号[" + sheetNo + "]は存在しません。");
}

// シートを読み込む
HSSFSheet workSheet = workBook.getSheetAt(sheetNo);

// 行のループ
for (int loopRow = 0; loopRow <= workSheet.getLastRowNum(); loopRow++) {
// 行情報を取得する
HSSFRow row = workSheet.getRow(loopRow);

StringBuffer buff = new StringBuffer();

// 列のループ
for (int loopCol = 0; loopCol < row.getLastCellNum(); loopCol++) {
// セル情報を取得する
HSSFCell cell = row.getCell((short)loopCol);

// セルに値がある場合
if (cell != null) {
// セルのタイプ毎に処理を行う
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_BOOLEAN:
buff.append(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
case HSSFCell.CELL_TYPE_FORMULA:
int format = cell.getCellStyle().getDataFormat();
if ((format >= 0 && format <= 13) ||
(format >= 23 && format <= 38) || format >= 42) {
double itemVal = cell.getNumericCellValue();
String itemStr = String.valueOf(itemVal);
if (itemStr.indexOf(".") < 0) {
buff.append((long)itemVal);
} else {
if (itemStr.indexOf("E") >= 0) {
buff.append((long)itemVal);
} else {
buff.append(itemVal);
}
}
} else if (format >= 14 && format <= 17) {
DateFormat dateFormat = DateFormat.getDateInstance();
Date date = cell.getDateCellValue();
buff.append(dateFormat.format(date));
} else if ((format >= 18 && format <= 22) ||
(format >= 39 && format <= 41)) {
DateFormat dateFormat = DateFormat.getTimeInstance();
Date date = cell.getDateCellValue();
buff.append(dateFormat.format(date));
}
break;
case HSSFCell.CELL_TYPE_BLANK:
case HSSFCell.CELL_TYPE_STRING:
buff.append(cell.getStringCellValue().
replaceAll("\\n", "").trim());
break;
}

// 最終カラム以外の場合
if ((loopCol + 1) < row.getLastCellNum()) {
// 区切り文字を付加する
buff.append(this.DELIMITER);
}
}
}
// 行データリストをListオブジェクトに追加する
this.lineDataList.add(buff.toString());
}
this.maxPosition = this.lineDataList.size();
} catch (Exception e) {
System.out.println(e.toString());
throw new IOException(e.toString());
}
}
----------------------------------------------------------------------

Java人
ベテラン
会議室デビュー日: 2005/06/24
投稿数: 94
投稿日時: 2005-10-27 19:12
先ほど投稿させていただいたソースに以下のメソッドがかけておりました。

private HSSFWorkbook setSheet(HSSFWorkbook wb,
HSSFSheet sheet,
HSSFCellStyle style,
String sheetName) {
//シート名のセット
wb.setSheetName(0, sheetName, HSSFWorkbook.ENCODING_UTF_16);
//フォント
HSSFFont font = wb.createFont();
//高さ
font.setFontHeightInPoints((short)11);
//フォント名
font.setFontName("MS ゴシック");
//文字色
font.setColor(HSSFColor.BLACK.index);
//スタイル
font.setItalic(false);
//取消線
font.setStrikeout(false);
//上付、下付
font.setTypeOffset(HSSFFont.SS_SUPER);
//フォントのセット
style.setFont(font);
//罫線のセット(下)
style.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
style.setBottomBorderColor(HSSFColor.BLACK.index);
//罫線のセット(左)
style.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
style.setLeftBorderColor(HSSFColor.BLACK.index);
//罫線のセット(右)
style.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
style.setRightBorderColor(HSSFColor.BLACK.index);
//罫線のセット(上)
style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
style.setTopBorderColor(HSSFColor.BLACK.index);
//背景色のセット
style.setFillForegroundColor(HSSFColor.BLACK.index);
style.setFillBackgroundColor(HSSFColor.WHITE.index);
style.setFillPattern(HSSFCellStyle.NO_FILL);
//センタリングのセット
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
return wb;
}
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-10-27 19:21
罫線、とか色、とかカラム数とかをもっと減らしてシンプルにして再現可能な最小限の状態を作り出してみてはいかがでしょうか。
うまく動くプログラムが別にあれば比較しやすくなるかと存じます。
masa
大ベテラン
会議室デビュー日: 2005/05/11
投稿数: 108
投稿日時: 2005-10-27 20:43
こんばんは。

やま勘で検証していませんが、row.getLastCellNum()で取得する値が
おかしくなっている可能性がありそうです。
想定どおりの数が取得出来ているかデバッグしてみて下さい。
Java人
ベテラン
会議室デビュー日: 2005/06/24
投稿数: 94
投稿日時: 2005-10-28 10:36
返信ありがとうございます。

>やま勘で検証していませんが、row.getLastCellNum()で取得する値が
>おかしくなっている可能性がありそうです。
>想定どおりの数が取得出来ているかデバッグしてみて下さい。
row.getLastCellNum()をデバッグしたところ、正しく取得できていませんでした。
HSSFSheetのgetRowメソッドからおかしくなっているみたいです。
Desmo
大ベテラン
会議室デビュー日: 2004/03/24
投稿数: 149
投稿日時: 2005-10-28 11:00
過去の記憶で再検証まではしていないのですが、
getLow()の引数って、確か 1から指定する必要があったように思います。
つまり 1行目は getLow(1)、2行目は getLow(2) といった具合。
getCell()の方は 0からの指定で良かったと思いますが。
掲載されたソースでは判断しかねますが、書込み側のプログラムで上記仕様に引っかかっているってことはありませんか?
それと、インギさんの助言の通り もう少しシンプルなプログラムで検証をしないと・・・

スキルアップ/キャリアアップ(JOB@IT)