質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

0回答

5868閲覧

apache poiを使用したExcelの出力について(セルの範囲指定コピーを実装したい)

guitairst_sei5

総合スコア4

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2019/08/20 10:23

編集2019/08/21 02:48

前提・実現したいこと

apache poiを使用してExcelファイルを作成するプログラムを組んでいます。
Javaのプログラムからデータベースに接続し、取得したデータを
Excelのフォーマットを読み込んで、転記するプログラムになります。
そのプログラムにおいてExcelファイルのシート中のセルを範囲指定し、
同じシートの指定した箇所にコピーしたいと考えています。
具体的には添付のようなイメージで実現したいです。
イメージ説明

試したこと

行と列を2次元ループで回す方法など調べてみましたが、添付の通り
コピー元の真横にデータをコピーしていき、3つコピーデータができた
時点で折り返し、取得した件数分コピーを行うといった実装方法が思いつかず
困っています。有識者の方がいらっしゃれば実装方法をご教授いただきたいです。

補足情報(FW/ツールのバージョンなど)

当方の環境は以下の通りです。

Windows10
poi-3.0-FINAL.jar
jre1.5
Excel2013

お力添えの程どうぞ宜しく御願い致します

補足情報(2019/08/20 追記)

Java

1 /** 2 * 指定した範囲のセルをコピーする。 3 * 4 * @param copyRow0 5 * 開始行 6 * @param copyColumn0 7 * 開始列 8 * @param copyRow1 9 * 終了行 10 * @param copyColumn1 11 * 終了列 12 * @param startRow 13 * 貼り付け行 14 * @param startColumn 15 * 貼り付け列 16 */ 17 @SuppressWarnings("deprecation") 18 public void copyCellArea(String orgSheetName, int copyRow0, int copyColumn0, int copyRow1, 19 int copyColumn1, int startRow, int startColumn) { 20 21 // シートオブジェクト生成 22 HSSFSheet sheet = wb.getSheet(orgSheetName); 23 List<Region> appendRegionList = new ArrayList<Region>(); 24 25 for (int i = 0; copyRow0 + i <= copyRow1; i++) { 26 for (int j = 0; copyColumn0 + j <= copyColumn1; j++) { 27 HSSFCell srcCell = getCell(copyRow0 + i, copyColumn0 + j, sheet); 28 HSSFCell destCell = getCell(startRow + i, startColumn + j, sheet); 29 // スタイルを取得 30 destCell.setCellStyle(srcCell.getCellStyle()); 31 destCell.setCellType(srcCell.getCellType()); 32 33 // 値の設定 34 switch (srcCell.getCellType()) { 35 case HSSFCell.CELL_TYPE_BOOLEAN: 36 destCell.setCellValue(srcCell.getBooleanCellValue()); 37 break; 38 case HSSFCell.CELL_TYPE_ERROR: 39 destCell.setCellValue(srcCell.getErrorCellValue()); 40 break; 41 case HSSFCell.CELL_TYPE_FORMULA: 42 destCell.setCellFormula(srcCell.getCellFormula()); 43 break; 44 case HSSFCell.CELL_TYPE_NUMERIC: 45 destCell.setCellValue(srcCell.getNumericCellValue()); 46 break; 47 case HSSFCell.CELL_TYPE_STRING: 48 destCell.setCellValue(srcCell.getStringCellValue()); 49 break; 50 } 51 52 // 結合の設定 53 for (int k = 0; k < sheet.getNumMergedRegions(); k++) { 54 Region region = sheet.getMergedRegionAt(k); 55 // 処理中のコピー元セルが結合セルである場合 56 if (region.contains(i, (short) j)) { 57 int newRow0 = startRow + i; 58 short newCol0 = region.getColumnFrom(); 59 int newRow1 = region.getRowTo() - region.getRowFrom() + startRow + i; 60 short newCol1 = region.getColumnTo(); 61 Region newRegion = new Region(); 62 newRegion.setRowFrom(newRow0); 63 newRegion.setColumnFrom((short) newCol0); 64 newRegion.setRowTo(newRow1); 65 newRegion.setColumnTo((short) newCol1); 66 boolean exist = false; 67 for (int n = 0; n < appendRegionList.size(); n++) { 68 Region exRegion = appendRegionList.get(n); 69 if (exRegion.contains(newRow0, newCol0)) { 70 // 既に存在する 71 exist = true; 72 break; 73 } 74 } 75 if (!exist) { 76 appendRegionList.add(newRegion); 77 break; 78 } else { 79 break; 80 } 81 } 82 } 83 // 幅サイズ調節 84 if (i == 0) { 85 sheet.setColumnWidth((short) (startColumn + j), sheet.getColumnWidth((short) (copyColumn0 + j))); 86 } 87 } 88 } 89 } 90 91 /** 92 * Cell を返す。 93 * 94 * @param row 95 * 行 96 * @param column 97 * 列 98 * @param sheet 99 * オブジェクト 100 * @return Cell 101 */ 102 protected HSSFCell getCell(int row, int column, HSSFSheet sheet) { 103 return HSSFCellUtil.getCell(HSSFCellUtil.getRow(row, sheet), column); 104 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2019/08/20 14:26

ループしていなくても良いですので, 一つでもコピー出来ているコードをご提示ください.
guitairst_sei5

2019/08/21 01:36

皆様、ご返信および質問へのご指摘ありがとうございます。 まず、ご指摘頂きました通り実装の答えだけを求めてしまう質問となってしまったことを お詫びします。申し訳ありません。 jimbe様> ご連絡ありがとうございます。 実はコピー処理自体実装が初でして、コピー処理の実装から行っております。 コピー処理ですが、まだ正しく動くかわかりませんが以下のように実装しています。 /** * 指定した範囲のセルをコピーする。 * * @param copyRow0 * 開始行 * @param copyColumn0 * 開始列 * @param copyRow1 * 終了行 * @param copyColumn1 * 終了列 * @param startRow * 貼り付け行 * @param startColumn * 貼り付け列 */ @SuppressWarnings("deprecation") public void copyCellArea(String orgSheetName, int copyRow0, int copyColumn0, int copyRow1, int copyColumn1, int startRow, int startColumn) { // シートオブジェクト生成 HSSFSheet sheet = wb.getSheet(orgSheetName); List<Region> appendRegionList = new ArrayList<Region>(); for (int i = 0; copyRow0 + i <= copyRow1; i++) { for (int j = 0; copyColumn0 + j <= copyColumn1; j++) { HSSFCell srcCell = getCell(copyRow0 + i, copyColumn0 + j, sheet); HSSFCell destCell = getCell(startRow + i, startColumn + j, sheet); // スタイルを取得 destCell.setCellStyle(srcCell.getCellStyle()); destCell.setCellType(srcCell.getCellType()); // 値の設定 switch (srcCell.getCellType()) { case HSSFCell.CELL_TYPE_BOOLEAN: destCell.setCellValue(srcCell.getBooleanCellValue()); break; case HSSFCell.CELL_TYPE_ERROR: destCell.setCellValue(srcCell.getErrorCellValue()); break; case HSSFCell.CELL_TYPE_FORMULA: destCell.setCellFormula(srcCell.getCellFormula()); break; case HSSFCell.CELL_TYPE_NUMERIC: destCell.setCellValue(srcCell.getNumericCellValue()); break; case HSSFCell.CELL_TYPE_STRING: destCell.setCellValue(srcCell.getStringCellValue()); break; } // 結合の設定 for (int k = 0; k < sheet.getNumMergedRegions(); k++) { Region region = sheet.getMergedRegionAt(k); // 処理中のコピー元セルが結合セルである場合 if (region.contains(i, (short) j)) { int newRow0 = startRow + i; short newCol0 = region.getColumnFrom(); int newRow1 = region.getRowTo() - region.getRowFrom() + startRow + i; short newCol1 = region.getColumnTo(); Region newRegion = new Region(); newRegion.setRowFrom(newRow0); newRegion.setColumnFrom((short) newCol0); newRegion.setRowTo(newRow1); newRegion.setColumnTo((short) newCol1); boolean exist = false; for (int n = 0; n < appendRegionList.size(); n++) { Region exRegion = appendRegionList.get(n); if (exRegion.contains(newRow0, newCol0)) { // 既に存在する exist = true; break; } } if (!exist) { appendRegionList.add(newRegion); break; } else { break; } } } // 幅サイズ調節 if (i == 0) { sheet.setColumnWidth((short) (startColumn + j), sheet.getColumnWidth((short) (copyColumn0 + j))); } } } } /** * Cell を返す。 * * @param row * 行 * @param column * 列 * @param sheet * オブジェクト * @return Cell */ protected HSSFCell getCell(int row, int column, HSSFSheet sheet) { return HSSFCellUtil.getCell(HSSFCellUtil.getRow(row, sheet), column); } 上記ソースを参考にしたURLですが、 https://guchi-programmer.blogspot.com/2014/05/poi.html になります。上記URLに記載されているロジックなのですが、当方で使用している apache-poiのバージョンよりも新しいバージョンで組んでいる?ようでして そのまま組み込もうと思ったのですが、うまくいきませんでした。 貼付したソースは上記URLのソースをeclipseを使ってコンパイルエラーが出ないようにした状態です。
jimbe

2019/08/21 02:24 編集

書いていませんでしたが, コードはご質問を修正してマークダウンで追加して頂けますか. > コピー処理ですが、まだ正しく動くかわかりませんが ではまず, コピー元からコピー1へ(仮に固定座標・固定範囲で)コピーするコードを動作させては如何でしょう. それからループなりで複数コピーするように拡張するほうが良いかと思います. >そのまま組み込もうと思ったのですが、うまくいきませんでした。 記事は(URLから)2014年5月に書かれたようです. 必要ならバージョン違い辺りもお調べになったほうがよいのではないでしょうか.
guitairst_sei5

2019/08/21 02:56

jimbe様> ご回答およびご指摘ありがとうございます。 >書いていませんでしたが, コードはご質問を修正してマークダウンで追加して頂けますか ご依頼の通り質問内容を修正致しました。 >コピー元からコピー1へ(仮に固定座標・固定範囲で)コピーするコードを動作 ありがとうございます。まずは固定値で動作するかどうか確認するようにしてみます。 なにぶん、貼付したコードもちゃんと動くのか・・という疑惑もありますのでそこから 確認していきたいと思います。 >バージョン違い辺りもお調べに バージョンの違いはあるかと思います。現にインポートするパッケージが当方の環境と参考にしたURLのソースとでは異なっていることが分かりました。 ただ、今回は現行資産の改修のみということでapache-poiのバージョンアップは考慮しないという 条件がありどうにか現行のバージョンでできないかと試行錯誤しているものです。
jimbe

2019/08/21 03:11

修正ありがとうございます. バージョン違いに付きましては, 「バージョンを(記事に合わせて)替えたらどうか」というお話ではありませんで, バージョンが違うならどう違うのかのドキュメント・記事を探して, (試行錯誤では無く)その情報から修正されたほうが良いのではということです.
guitairst_sei5

2019/08/21 04:09

jimbe様> ご指摘ありがとうございます。 バージョンの差異についてはもう少し詳細に調べてみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問