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

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

ただいまの
回答率

90.53%

  • Java

    15505questions

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

poiでテンプレートのExcelを読み込んでダウンロードする時

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 8,599

tera1

score 72

お世話になっております。

java の poi3.14を使用して、テンプレートExcelを読み込んで、データを書き込んでファイルをダウンロードするSevletを実装しました。

ただ、以下のようなコードですと、
例えば、データ貼り付けのシートに
1回目のリクエストは
1-10行目にデータが張り付き、
2回目のリクエストでは、パラメータが代わり貼り付けデータが
1-5行目となると、
6-10行目が前回の不要なデータが入ってしまいます。

// ファイルパスを取得します
        String filePath = getServletContext()
                .getRealPath("/WEB-INF/excel/" + getServiceType() + "/" + getExcelFileName());

// テンプレートからExcel読み込み
            wb = new XSSFWorkbook(filePath);

そのあと、シート指定して、wbにデータ書込をごにょごにょ行った後、
以下、ダウンロード処理をします。

response.setContentType("application/vnd.ms-excel.sheet.macroEnabled.12");
        String fileName = null;
        try {
            fileName = new String(getExcelFileName().getBytes("Windows-31J"), "ISO-8859-1");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        response.setHeader("Content-Disposition", "attachments; filename=\"" + fileName + "\"");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);

        try {
            OutputStream out = response.getOutputStream();
            wb.write(out);
            out.close();
        } catch (IOException e) {
                   e.printStackTrace();
        } finally {
            wb.close();
        }

対応として
wbで読み込んでいる前回のExcelがあれば、削除してから開くようにする。
としたいですが、前回読み込んでいるExcelファイルパスが不明のため、
実装方法がわからない状態です。

上記以外の対応として、以下のようなコードを参考に、
new File("テンプレートExcelファイルパス") して、新しく読込
それを、FileInputStreamにいれて
FileOutputStreamで書き出しすれば、うまく動くかと思い試してみましたが、書き出し部分が、new FileOutputStream( f );では、空のExcelファイルがダウンロードされてしまい、response.getOutputStream()でないと正常ファイルがダウンロードされませんでした。

import java.io.*;
import org.apache.poi.ss.usermodel.*;

public class PoiEdit{
public static void main(String[] args) throws Exception{
File f = new File("Book1.xls"); // 既存のExcelファイル名を指定
InputStream is = new FileInputStream( f );
Workbook wb = WorkbookFactory.create( is ); // メモリ上に展開
is.close(); //ここで入力ストリームを閉じる

// 編集したいシート、列、セルを指定
Sheet s =wb.getSheetAt(0);
Row r = s.getRow(1);
Cell c = r.getCell(1);
// この場合B2セルに「あいう」をセット
c.setCellValue( "あいう" );
c.setCellType( Cell.CELL_TYPE_STRING );

// 編集した内容の書き出し
OutputStream os = new FileOutputStream( f );
wb.write( os );
}


対応方法について、教えて頂ければ幸いです。
大変お手数をお掛けしますが、ご回答いただければ幸いでごす。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

check解決した方法

0

どうやら、前回の内容が保存されてしまうのは、
poi3.11から、そう変わったようです。

3.10.1にすると、保存されてしまう現象は
ありませんでした。

ご相談に乗って頂き、感謝します!
ありがとうございました!

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

XSSFWorkbookは自動で保存はしないので、最初のコードでもうまくいく気がします。
どこかで、wb.writeを実行してファイルを保存していたりしませんか?

あと、XSSFWorkbookの変数wbはどこで定義していますか?
Servletのインスタンス変数として定義していませんか?

Servletのインスタンスは、リクエスト毎に生成されるものではなく
1つのインスタンスを複数のリクエストで共有して使うので、
インスタンス変数で定義されていた場合想定外の更新が行われたりするので、
メソッド内のローカル変数として定義した方が良いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/20 18:39

    ご回答ありがとうございます。
    最初のコードで、ダウンロードのヘッダー追加処理後にwb.writeをしています。それ以外ではしておりません。

    はい、変数は、関数内で宣言して、関数どおしで使いまわしているだけで、サーブレットのメンバ変数には定義していません。

    テンプレートを取得するfilePathをダンプしますと、eclipesの関係か実態がある位置とは別のパスからエクセルが作成されており、そのファイルが
    前回保存したもののようです。

    ただ、これを手動で消してしまうと、
    今度、ファイルがみつからないになります。

    ビルドやクリーンで生成されるものでもなく、
    生成タイミングが不明です。。

    キャンセル

0

回答ありがとうございます。

テンプレートを取得するfilePathをダンプしますと、eclipesの関係か実態がある位置とは別のパスからエクセルが作成されており、そのファイルが 
前回保存したもののようです。

パスがおかしくなるのは、初回もでしょうか?
それとも初回は想定通りのパスでしょうか?

あと、EclipseでWTPなどで起動しないで、
warファイルをTomcat等に直接デプロイした場合は
どのような挙動になるか確かめてもらうことは可能でしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/20 18:54

    ご回答ありがとうございます!!

    ```java
    // ファイルパスを取得します
    String filePath = getServletContext()
    .getRealPath("/WEB-INF/excel/" + getServiceType() + "/" + getExcelFileName());

    System.out.println("filePath: " + filePath);
    ```

    実際テンプレファイルを配置した場所は、以下になるのですが、
    C:\Users\win7\workspace\app\src\main\webapp\WEB-INF\excel\test\xxx.xlsm

    system.out.printinでは、以下のパスが出力されます。
    C:\Users\win7\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\app\WEB-INF\excel\test\xxx.xlsm

    ↑に前回の状態で保存されているようで、warで書き出したアプリも同じ動作をしました。

    キャンセル

同じタグがついた質問を見る

  • Java

    15505questions

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