プロが教える店舗&オフィスのセキュリティ対策術

現在、poiで日報システムを作成しております。
入力されたデータはexcelに出力されるような処理をしました。
日報を入力し、ボタンを押されるたびに既存のexcelファイルに上書きされるようにしたいです。
もしエクセルが新規で出力される場合には1行目には見出しを、2行目には入力された内容が出力されます。
次にこのシステムを使った人が書き込みをした場合には3行目に内容が出力されるようにしていきたいです。
このためにexcelを読み込んで、空白セルを確認する処理をすればいいのでしょうが、試行錯誤しました、まず自分で保存先に空のExcelを作らないといけないということと、1回目の入力では正常に2行目まで出力されていますが、もう1度入力をし、出力をすると1,2行目が消えて3行目に書き込みがされるだけになってしまいます。
そこで2点ございます。
(1)2回目の出力で1,2行目が消えてしまうのはプログラムの組み方に誤りがあるのでしょうが、お手上げ状態です。
(2)excelが存在しない場合はこのシステム上で新たに作成をしてくれるようにもできるのでしょうか?
ご教授いただければと思います。

public void ExcelOutput() {

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet();

/*
* ファイルを読み込みし行数が「0」
* 何も書き込みがされていない場合にはヘッダと1つめの行(2行目)を書き込み
*/
if(ExcelInput() == 0){
Row head = sheet.createRow(0);

Cell head1 = head.createCell(0);
Cell head2 = head.createCell(1);

head1.setCellValue("会社");
head2.setCellValue("報告者");

CellStyle styleHead = wb.createCellStyle();
styleHead.setFillPattern(CellStyle.SOLID_FOREGROUND);
styleHead.setFillForegroundColor(IndexedColors.RED.getIndex());

head1.setCellStyle(styleHead);
head2.setCellStyle(styleHead);

Row contents = sheet.createRow(1);
Cell contents1 = contents.createCell(0);
Cell contents2 = contents.createCell(1);

contents1.setCellValue(CompanyInput.getText());
contents2.setCellValue(NameInput.getText());
FileOutputStream out = null;

try{
out = new FileOutputStream("ccc.xls");
wb.write(out);
}catch(IOException e){
//System.out.println(e.toString());
}finally{
try {
out.close();
}catch(IOException e){
//System.out.println(e.toString());
}
}
}
/*
* すでにエクセル作成済み(1,2行目に入力がされている)場合
* 途中から書き込み
*/
else{
Row contents = sheet.createRow(CompanyExcelInput());
Cell contents1 = contents.createCell(0);
Cell contents2 = contents.createCell(1);

contents1.setCellValue(InterviewPersonInput.getText());
contents2.setCellValue(NameInput.getText());
FileOutputStream out = null;

try{
out = new FileOutputStream("ccc.xls");
wb.write(out);
}catch(IOException e){
//System.out.println(e.toString());
}finally{
try {
out.close();
}catch(IOException e){
//System.out.println(e.toString());
}
}
}
}

public int ExcelInput(){
int rowNullCount = 0;
try{
//Excelのワークブックを読み込む
POIFSFileSystem filein = new POIFSFileSystem
(new FileInputStream("ccc.xls"));
HSSFWorkbook wb = new HSSFWorkbook(filein);
//シートを読み込む
HSSFSheet sheet = wb.getSheetAt(0);
//空行を検索し、空行を保持する
for(rowNullCount = 0; rowNullCount <= sheet.getLastRowNum(); rowNullCount++) {
HSSFRow row = sheet.getRow(rowNullCount);
if(row == null){
break;
}
}
} catch(IOException ioe) {
// TODO
}
return rowNullCount;
}

ExcelInputとExcelOutputはボタンのactionPerformedで読み込んでいます。
宜しくお願い致します。

A 回答 (1件)

こんにちは。



既存のソースは一部抜粋のようですのであまり解析していません。
・ファイルが存在した場合はそのファイルを利用、ファイルが存在しない場合は新規作成
・新規作成の場合は先頭行に見出し
・その後は次の行から作成されていく

という仕様で簡単なサンプルですが作ってみました。
これを参考にどうにかなるでしょうか。
(動きはソース中のコメントを参考にしてください)



public void execute() {

FileInputStream in = null;
HSSFWorkbook workbook = null;
HSSFSheet sheet = null;
try {
// test.xlsを読み込んでみる
// 読み込めた場合は既存のファイルを利用する
in = new FileInputStream("test.xls");
workbook = new HSSFWorkbook ( in );
sheet = workbook.getSheetAt ( 0 );
} catch ( IOException e ) {
// test.xlsが読み込めない場合はここで新規作成
workbook = new HSSFWorkbook();
sheet = workbook.createSheet("test");
// 見出しを作る
Row row = sheet.createRow(0);
Cell cell1 = row.createCell(0);
Cell cell2 = row.createCell(1);
cell1.setCellValue ( "会社" );
cell2.setCellValue ( "報告者" );
}
// 行を1行目から走査する
// 1行目は見出しのため、チェック対象外
Row row = null;
Cell cell = null;
int i = 1;
for ( ; ; i ++ ) {
// i番目を取得する
row = sheet.getRow(i);
if ( row == null )
// i番目が取得できなかったら行を作成
row = sheet.createRow(i);
// 0番目のセルを取得する
cell = row.getCell(0);
if ( cell == null )
// 0番目のセルが取得できなかったら新規作成
cell = row.createCell(0);
// そのセルに値が入っていない場合はループを抜ける
if ( "".equals(cell.getStringCellValue()) ) break;
}

// 値の入っていないセルでループを抜けるため、すなわち最新の行に内容を書き込む
cell.setCellValue ( i + "行目に書いた" );

try {
if ( in != null )
in.close();
} catch ( IOException e ) {
e.printStackTrace();
}


FileOutputStream out = null;
try {
// ファイルの書き出し
out = new FileOutputStream("test.xls");
workbook.write ( out );
} catch ( IOException e ) {
e.printStackTrace();
} finally {
try {
out.close();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}

この回答への補足

ご教授頂きありがとうございます。
教えて頂いたプログラムを参考にしましたところうまくいきました。

ところがここでまた1つ問題点が発生してきてしまいました。
業務日報には4つの項目があり、そこを入力すると1行目のDセルまで値が入ります。
次にシステムから上書きをすると正常に2行目に書き込みはされるのですが、1行目のBCDセルの情報が消えてしまい、Aセルのみ残った状態になっています。
これを繰り返すと最新で書き込みした行以外の物はすべてAセルしか情報が残らなくなってしまいます。
この現象を回避する方法はございますでしょうか?
宜しくお願いいたします。

public void execute() {

FileInputStream in = null;
HSSFWorkbook workbook = null;
HSSFSheet sheet = null;
try {
// test.xlsを読み込んでみる
// 読み込めた場合は既存のファイルを利用する
in = new FileInputStream("test.xls");
workbook = new HSSFWorkbook ( in );
sheet = workbook.getSheetAt ( 0 );
} catch ( IOException e ) {
// test.xlsが読み込めない場合はここで新規作成
workbook = new HSSFWorkbook();
sheet = workbook.createSheet("test");
// 見出しを作る
Row row = sheet.createRow(0);
Cell cell1 = row.createCell(0);
Cell cell2 = row.createCell(1);
Cell cell3 = row.createCell(2);
Cell cell4 = row.createCell(3);

cell1.setCellValue("会社");
cell2.setCellValue("報告者");
cell3.setCellValue("場所");
cell4.setCellValue("時間");

}

// 行を1行目から走査する
// 1行目は見出しのため、チェック対象外
Row row = null;
Cell cell1, cell2, cell3, cell4 = null;
int i = 1;
for ( ; ; i ++ ) {
// i番目を取得する
row = sheet.getRow(i);
if ( row == null )
// i番目が取得できなかったら行を作成
row = sheet.createRow(i);
// 0番目のセルを取得する
cell1 = row.getCell(0);
if ( cell1 == null )
// 0番目のセルが取得できなかったら新規作成
cell1 = row.createCell(0);
cell2 = row.createCell(1);
cell3 = row.createCell(2);
cell4 = row.createCell(3);

// そのセルに値が入っていない場合はループを抜ける
if ( "".equals(cell1.getStringCellValue()) )
break;
}

// 値の入っていないセルでループを抜けるため、すなわち最新の行に内容を書き込む
cell1.setCellValue(CompanyInput.getText());
cell2.setCellValue(NameInput.getText());
cell3.setCellValue(WhereInput.getText());
contents4.setCellValue(TimeInput.getText());



try {
if ( in != null )
in.close();
} catch ( IOException e ) {
e.printStackTrace();
}

FileOutputStream out = null;
try {
// ファイルの書き出し
out = new FileOutputStream("test.xls");
workbook.write ( out );
} catch ( IOException e ) {
e.printStackTrace();
} finally {
try {
out.close();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}

補足日時:2013/06/14 14:05
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
新規で質問をたてさせていただきます、宜しくお願いいたします。

お礼日時:2013/06/14 14:07

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!