POIでExcelに時刻の値を出力したい

このQ&Aのポイント
  • 現在、JAVAでEXCELで運用している社内勤務表をWebから入力できるシステムを開発しています。
  • 現在の問題は、POIライブラリを使用して勤務開始時間や勤務終了時間の値をExcelのセルに出力する際に、h:mm形式の値が出力できないことです。
  • 既に試した方法(文字列やシリアル値としての出力など)では期待通りの結果が得られず、値も表示もh:mm形式で出力する方法がわかりません。ご教授頂けないでしょうか。
回答を見る
  • ベストアンサー

POIでExcelに時刻(h:mm)の値を出力したい

お世話になっております。 現在JAVA勉強という名目でEXCELで運用している社内勤務表をWebから入力できるシステムを開発しています。(好みによりExcel直接編集とWebによる編集どちらかを選べる) 現状の問題としてはPOIライブラリにより勤務開始時間、勤務終了時間の値をExcelのセルに出力するところで h:mm (例えば[10:30])という値が出力できないことです。(既存の書式に合わせた値の出力ができない) 文字列(先頭に'が付く)やシリアル値として出力することは可能ですが、ただ単純に[10:30]と出力することができません。 【実現したいExcelの出力結果】(JavaのString文字列"10:30"を元に出力) 値:[10:30] 表示:[10:30] ※Excelのセルは表示と値が異なる場合があるが両方共 h:mm 形式で出力したい。 【試行錯誤した出力結果】 (1)文字列として出力する 値:['10:30] 表示:[10:30] ※表示は期待通りだが値の先頭に'がついてしまいうまくいかない。 ※出力した値は他のセルの計算式で参照するので'がついてるのは問題あり。 (2)Date型で出力し書式を h:mm 形式にする 値:[613666:30:00] 表示:[10:30] ※表示は期待通りだが値がシリアル値になってしまいうまくいかない。 ※ただし m/d/yy h:mm 形式を出力するとシリアル値にならない。(何故だろう) ※シリアル値ではExcel直接編集の際に人が編集しにくい値なので問題。 実際Excelでは値も表示も[10:30]というセルはキーボード入力で簡単に作成できるのでPOIで出力できないとはとても思えません。 どうすれば[10:30]という値が出力できるか教えていただけないでしょうか。 よろしくお願いいたします。 ----------------------------------------------------------------------- 【使用しているPOI】 バージョン:3.2 ダウンロードしたファイル:poi-bin-3.2-FINAL-20081019.zip ----------------------------------------------------------------------- 【試行錯誤したプログラム】 public class CellOutput{ public static void main(String[] args){ HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet(); HSSFRow row = sheet.createRow(1); HSSFCellStyle style = workbook.createCellStyle(); style.setDataFormat(HSSFDataFormat.getBuiltinFormat("h:mm")); try { // テスト1(文字列で出力) HSSFCell cell1 = row.createCell((short)0); cell1.setCellValue("10:30"); // テスト2(Dateで出力 書式設定無) HSSFCell cell2 = row.createCell((short)1); SimpleDateFormat hhmmFormat = new SimpleDateFormat("h:mm"); Date time = hhmmFormat.parse("10:30"); cell2.setCellValue(time); // テスト3(Dateで出力 書式設定有) HSSFCell cell3 = row.createCell((short)2); cell3.setCellValue(time); cell3.setCellStyle(style); // テスト4(Dateで出力 m/d/yy h:mm形式) HSSFCell cell4 = row.createCell((short)3); HSSFCellStyle style2 = workbook.createCellStyle(); style2.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm")); cell4.setCellValue(time); cell4.setCellStyle(style2); } catch(Exception e){ } FileOutputStream out = null; try{ out = new FileOutputStream("sample.xls"); workbook.write(out); }catch(IOException e){ System.out.println(e.toString()); }finally{ try { out.close(); }catch(IOException e){ System.out.println(e.toString()); } } } } -----------------------------------------------------------------------

この投稿のマルチメディアは削除されているためご覧いただけません。
  • estmo
  • お礼率36% (4/11)
  • Java
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.1

できないわ。 残念ながら。 それが証拠に、 最初に10:30と入力したExcelのセルから getCellStyleした結果をsetCellStyleしても 反映されないわ。 テスト3の方法を取るのが一番と思うわ。 それと、POI3.2は ・createCellでshortへのキャストは不要よ。 ・テスト1で、文字列は必ずHSSFRichTextStringに変換すること。

estmo
質問者

お礼

askaaskaさん 回答ありがとうございます。 10:30という値はPOIでは出力できないんですね。 この質問の前に半日調べてわからなかったので、もしかして無理かなとは思っていたんですが……残念です。 >・createCellでshortへのキャストは不要よ。 >・テスト1で、文字列は必ずHSSFRichTextStringに変換すること。 了解しました。 入門サイトのプログラムを真似たら警告が出るようなので直します。 裏技があるかもしれないのでもう少し質問をオープンにしておきます。(基本無理ということは納得したんですが一応) POIの中身をいじるとか(無理かな?)

その他の回答 (2)

  • sonar5
  • ベストアンサー率0% (0/1)
回答No.3

excelの時刻は、少数点以下のシリアル値を設定します。 excelの書式は、時刻とします。 excelのシリアル値は1900年1月1日が1なので 日付なしの時刻は、少数以下の数値です。 (例) 9:15 シリアル値=9*(1/24) + 15*(1/24/60) これをpoiのsetCellValueで設定すると時刻のみとなります。 XXX.setCellValue(シリアル値); (PGの例) SetCellTime(10,2,"12:53"); private static void SetCellTime(HSSFSheet sheet,int r,int c,String data){ HSSFRow row = sheet.getRow(r-1); HSSFCell cell = row.getCell(c-1); double s; double hh; double mm; //シリアル値への変換 hh = Double.parseDouble(data.substring(0,2))*(1.0/24.0); mm = Double.parseDouble(data.substring(3,5))*(1.0/24.0/60.0); s = hh + mm; cell.setCellValue(s); return; }

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.2

これはただの掲示板的レス > POIの中身をいじる それでできるなら既に誰かがやっている気もするけど 余裕があったら見てみようかしら。 Excel2007対応なら何とかなりそうな気もするんだけどね。 xlsxだし。

関連するQ&A

  • POIで出力したExcelファイルで変更メッセージ

    POIで出力したExcelファイルを開いてすぐに閉じると 「'○○.xls'への変更を保存しますか?」といったメッセージが出てしまい、 何とかならないかと困っている状況です。 全体的な流れとしては単純で、テンプレートとなるExcelファイルを用意して それをPOIを利用して読み込み、値をセットして、別名で保存しなおしています。 テンプレートは、SUM関数が書かれただけのシンプルなものです。 POIのバージョンは、3.8です。 JREは、1.5.0_15を使用しています。 プログラムは以下になります。 -----------------------------------------------------   int rowNo = 0;   int colNo = 0;      FileOutputStream fileOutputStream = null;   try{    //EXCEL読み込み    HSSFWorkbook inputWorkbook = new HSSFWorkbook(     new FileInputStream(new File("C:\\Test1.xls")));    fileOutputStream = new FileOutputStream("C:\\結果.xls");        //最初のシートを取得する    HSSFSheet sheet = inputWorkbook.getSheetAt(0);    sheet.setForceFormulaRecalculation(true);        //ROW取得    HSSFRow row = sheet.getRow(rowNo);    if(null == row)row = sheet.createRow(rowNo);    //CELL取得    HSSFCell cell = row.getCell(colNo);    if(null == cell)cell = row.createCell(colNo);    //値を書き込む    cell.setCellValue(1);        //EXCELファイル書き出し    inputWorkbook.write(fileOutputStream);   }catch (Exception e) {    e.printStackTrace();   }finally{    try{     if(null != fileOutputStream)fileOutputStream.close();    }catch (Exception e) {     e.printStackTrace();    }   } ----------------------------------------------------- 以下の一文を除くと、変更メッセージは表示されなくなります。 sheet.setForceFormulaRecalculation(true); しかし、この一文がないとSUM関数の計算が動作しません。 記述、認識の不備、また解決に向けた良い方法がありましたら ご教授のほど、よろしくお願いします。

    • ベストアンサー
    • Java
  • POIの出力場所について

    お世話になります。 POI 出力などで検索を行いましたが上手くHITしませんでしたのでご質問させて頂きます。 例えば HSSFWorkbook workbook = null; FileOutputStream out = null; out = new FileOutputStream("質問.xls"); workbook.write(out); など記述し出力すると思うのですが「質問.xls」を C:\testに指定して出力したいなど指定した階層に出力するということは出来るでしょうか。

    • ベストアンサー
    • Java
  • java Excel書き込み

    前回質問をさせて頂き、 教えて頂いたプログラムを参考にしましたところうまくいきました。 ところがここでまた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(); } } } }

    • ベストアンサー
    • Java
  • POIのHSSFを用いたエクセルでのフォント指定について

    POIのHSSFについてお教えください。 JDK1.5.0_12 / poi-3.0.2を使用しています。 フォントは、デフォルトでは "Arial" なので、セル毎に"MS 明朝"を指定すると、初めはMS明朝に変更できたのですが、そのうち"表示形式を追加できません。" とエクセルに表示され、エクセルが開けなくなりました。調べると、ブックに含まれるセルの書式の組み合わせが約 4,000 を超える場合に発生し、すべてのセルに同じフォントを使用すると、書式設定の組み合わせ数が減少するとのこと。HSSFで、デフォルトのフォントをワークブックまたはシート指定で直接変更することはできるのでしょうか。 下記が、今回のコードの一部です。 HSSFWorkbook wb = new HSSFWorkbook(); HSSFFont font1 = wb.createFont(); font1.setFontName("MS 明朝"); を指定し、以下を、行毎に、セルの数だけ(CellPositionを変動)繰り返しました。 HSSFCell cell = row.createCell((short)CellPosition); HSSFCellStyle style1 = wb.createCellStyle(); style1.setFont(font1); cell.setCellStyle(style1); 宜しくお願い致します。

    • ベストアンサー
    • Java
  • Java swing エクセル書き込み

    現在、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で読み込んでいます。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • エクセルの時刻の表示について

    エクセルの時刻の表示についてです。 24時間以上の合計時間を正しく表示するために、 [h]:mmという表示形式にしています。 ここで、24:00と入力したら、実際のデータは 1900/1/1 0:00:00になってしまいます。 表示は、24:00だし、時間の合計もうまくいくのですが。 シリアル値がなんか関係あるんでしょうね・・・ でも、しっくりこないので、 実際のデータを24:00にしたいのです。方法はありますか? お教えください。宜しくお願いします。

  • Excelに時刻を入れたい

    はじめまして。 JAVA初心者です。 DBから取得したデータ「09:00」をExcelに入れようとしているんですが、表示された結果が正しくないのです。 DBからTimeタイプとして入れたら、セル値がシリアルになってしまう。 他、Stringとしたら、セル値にアポストロフィが付いてしまう。 今のところ解決方法はありません。 どうすれば、正しい結果(9:00)が表示されるのでしょうか。 教えていただけませんか? ついでに、既存エクセルの書式は「時刻」です。 ソースは以下の通りです。(Timeタイプとする) -------------------jsp ソース------------------ FileInputStream inputStream = null; FileOutputStream outputStream = null; File excel = new File("C:\\123123.xls"); inputStream = new FileInputStream(excel); HSSFWorkbook workBook = new HSSFWorkbook(inputStream); HSSFSheet newSheet = workBook.getSheetAt(0); HSSFRow newRow = newSheet.getRow(16); HSSFCell newCell1 = newRow.getCell((short) 6); java.sql.ResultSet rs = null; rs = DBtest.DBGetdate(); Time modifyTimeTemp = null; HSSFRow newRowtemp = newSheet.getRow(18); HSSFCell newCell1temp = newRow.getCell((short) 6); while(rs.next()){ modifyTimeTemp = rs.getTime("Time"); } //newCell1temp:正しく入力されたデータ newCell1.setCellStyle(newCell1temp.getCellStyle()); newCell1.setCellValue(modifyTimeTemp); try{ response.setContentType("application/msexcel"); response.setHeader("Content-Disposition", "attachment; filename=jsp.xls"); OutputStream outs = response.getOutputStream(); workBook.write(outs); outs.close(); }catch(Exception e){ e.printStackTrace(); }

    • ベストアンサー
    • Java
  • PHPからExcel出力について

    現在、プログラム(PHP)でデータ出力の機能を作成しているのですが、Excel出力で (1)ブックが開く (2)データを表示 (3)保存 以上の一連の動作はできるのですが、ブックを開いた際にExcel上に「ファイルへのダメージが深刻であり修復は不可能です。数式と値の回復を試みましたが、消失または破損したデータが含まれる可能性があります」といったエラーが表示されてしまいます。 コード変換もしているし、spreadsheet_excel_writerのパッチも当てましたが改善されません。 まだプログラミングが不慣れなもので、解決策が見当たらずに困っています。 どなたかご教授頂けますと助かります。よろしくお願いいたします。 ※申し訳ありません、データを添付していませんでしたので再投稿させていただきました。 ============================================================== //-----------ココから上はデータを取得する関数でデータを取得しています----------- $workbook = new Spreadsheet_Excel_Writer(); $workbook->setVersion(8); $workbook->setVersion(0x0500); $tablename = "sampletable"; $worksheet =& $workbook->addWorksheet($tablename); $worksheet->setInputEncoding("sjis"); $format =& $workbook->addFormat(); $format->_font_name = mb_convert_encoding("MS UI Gothic", "shift_jis"); $format->setBold(); $format->setFgColor(31); //Excelでいうところの見出し部分 $worksheet->write(0,0,"○○"); $worksheet->write(0,1,"○○"); $worksheet->write(0,2,"○○"); $worksheet->write(0,3,"○○"); $worksheet->write(0,4,"○○"); $worksheet->write(0,5,"○○"); $worksheet->write(0,6,"○○"); $worksheet->write(0,7,"○○"); $worksheet->write(0,8,"○○"); //-------ココから下はforeachでデータを表示($worksheet->write)させています-------

    • ベストアンサー
    • PHP
  • エクセルで左隣シートの特定のセルの値を表示させたい

    エクセルで左隣シートの特定のセルの値を表示させたいのですが、 どのようにすればよいでしょうか? 似たような質問の回答をいくつか試したのですが、 よく理解できていないため、うまく応用できずエラーになってしまいます。 ="No."&SUBSTITUTE(MID(CELL("filename",$A$1),FIND("(",CELL("filename",$A$1))+1,5),")","") とか =INDIRECT(SUBSTITUTE(RIGHT(CELL("filename",A1),LEN(CELL("filename",A1))-FIND("]",CELL("filename",A1))),"日","")-1&"日!A"&ROW(F24)) とか =SUM(INDIRECT("'"&(SUBSTITUTE(RIGHT(CELL("filename",A1),LEN(CELL("filename",A1))-FIND("]",CELL("filename",A1))),"日","")-1)&"日'!c5"),F24) とか といった式が参考になりそうですが、結局どう書き変えればいいのかわかりません。。 具体的には、シート名が「04」「05」…「12」「01」「02」「03」と1年分の12シートあります。 半角2桁のみのシート名です。 05以降のシートには、それぞれF1セルに、 「左隣シートのF24のセルの値を表示させたい」のです。 (F24のセル自体は「=F11+F23」という式が入力されています。) 例の式の「日」とか「row()」とかは必要ないと思いますが、 消しただけではムリそうなのでそのままコピーしています。 おわかりになる方、どうぞよろしくお願いします。

  • POIのHSSFCellStyleクラスを継承したい

    POI(http://jakarta.jp/poi/index.html)なる物を使ってExcelを作成するプログラムを作成しています 複数のプログラムで使用するため、機能を1つにまとめたクラスを用意し、そのクラスをプログラムで使用しようと考え作成していたのですが セル属性(HSSFCellStyle)を設定するクラスもまとめ用としたところ コンストラクタがprotected?のため、extendsして作成することができません (new HSSFCellStyle()ということも出来ません) HSSFCellStyleクラスで使用する機能をまとめたクラスを用意したいのですが 方法をご存知の方、よろしくお願いします HSSFCellStyle style = wb.createCellStyle(); style.setFillBackgroundColor(HSSFColor.AQUA.index); style.setFillPattern(HSSFCellStyle.BIG_SPOTS); HSSFCell cell = row.createCell((short) 1); cell.setCellStyle(style);

    • ベストアンサー
    • Java