サーブレットから直接CSVファイルをダウンロードするサンプルです。
配列の内容をCSV出力するだけの簡単なサンプルです。

お仕事では、データベースの検索キーなどをパラメータで受け取って、検索結果をCSV出力する事が多いと思います。
そんなサンプルもそのうち作ろうと思います。
日本語ファイル名対応はこちら → 日本語ファイル名対応のCSV出力サンプル

ファイルの配置

/CONTEXT_ROOT
┣ WEB-INF
┃┣ src
┃┃┗ DynamicCsvServlet.java
┃┗ web.xml
┗ jsp
 ┗ dynamic_csv.jsp

DynamicCsvServlet.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
public class DynamicCsvServlet extends HttpServlet {
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
      IOException {
    // POSTメソッドでアクセスが来てもGETメソッドで全部処理します。
    doGet(req, resp);
  }
 
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
      IOException {
 
    // CSV出力用データ
    String[][] rows = {
        { "0", "ダイナミック", "dynamic@example.com" },
        { "1", "ホゲ", "hoge@example.com" },
        { "2", "モゲ", "moge@example.com" },
        { "3", "マゲ", "mage@example.com" },
        { "4", "フゥ", "foo@example.com" },
        { "5", "バァ", "bar@example.com" },
        { "6", "グゥ", "goo@example.com" }
        };
 
    // 文字コード設定
    resp.setContentType("text/html; charset=UTF-8");
    // ファイル名設定(ファイル名を設定しないと、htmlとして画面に表示されてしまいます
    resp.setHeader("Content-Disposition", "attachment; filename=\"dynamic.csv\"");
 
    // CSVデータ作成
    StringBuffer sb = new StringBuffer();
    for (String[] row : rows) {
      for (int i = 0; i < row.length; i++) {
        if (i == 0) {
          sb.append("\"");
        } else {
          sb.append("\",\"");
        }
        sb.append(row[i]);
 
        if (i == row.length - 1) {
          sb.append("\"\n");
        }
      }
    }
 
    // レスポンスにCSV出力
    PrintWriter w = resp.getWriter();
    w.print(sb.toString());
    w.flush();
  }
}
 
  • アクセスされると、ファイルではなくHttpServletResponseに直接CSVを出力するサーブレットです。
  • CSVダウンロードのために、文字コード、ファイル名を設定しています。
    • HttpServletResponseにファイル名とコンテンツ(CSV文字列)を与える事で、ブラウザはCSVファイルのダウンロードだと認識します。

// 文字コード設定
resp.setContentType("text/html; charset=UTF-8");
  • ここで、出力するCSVの文字コードを「UTF-8」に指定しています。
  • 他の文字コードにする場合「UTF-8」の部分を修正します。

// ファイル名設定(ファイル名を設定しないと、htmlとして画面に表示されてしまいます
resp.setHeader("Content-Disposition", "attachment; filename=\"dynamic.csv\"");
  • ここで、ダウンロードするファイル名を設定しています。
  • ファイル名を設定しないと、ブラウザにhtmlとしてCSVの文字列が表示されてしまいます。

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
 
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">
 
  <!-- サーブレットの宣言 -->
  <servlet>
    <servlet-name>dynamiccsvservlet</servlet-name>
    <servlet-class>DynamicCsvServlet</servlet-class>
  </servlet>
 
  <!-- サーブレットとurlのマッピング -->
  <servlet-mapping>
    <servlet-name>dynamiccsvservlet</servlet-name>
    <url-pattern>/dynamiccsvservlet</url-pattern>
  </servlet-mapping>
</web-app>
 
  • サーブレットの宣言とURLのマッピングです。
  • この時点で、Tomcatを起動して「http://localhost:8080/CONTEXT_ROOT/dynamiccsvservlet」にアクセスすると、CSVファイルのダウンロードダイアログが出てくると思います。
※ブラウザの種類や設定によって動作が違います。


dynamic_csv.jsp

<%@ page language="java" contentType="text/html; charset=UTF8" pageEncoding="UTF-8" %>
<html>
  <body>
    動的CSVダウンロード(GET):<a href='<%=request.getContextPath()+"/dynamiccsvservlet"%>'>
    <%=request.getContextPath()+"/csvservlet"%></a><br>
  <form action='<%=request.getContextPath()+"/dynamiccsvservlet"%>' method='GET'>
    <input type="submit" value="動的CSVダウンロード(POST)" />
  </form>
  </body>
</html>
 
  • 動的にCSVを出力するサーブレットへのリンクとフォームを表示するJSPです。
  • ブラウザに直接URL入力してもアクセス出来ますが、せっかくだからJSPも用意しました。

request.getContextPath()
  • これは、Webアプリのコンテキストパスを出力してくれるメソッドです。
    • これに続けてサーブレットマッピングで指定したURLを記入すると、リンククリックやサブミットボタンでサーブレットにアクセス出来るのです。


ブラウザでアクセス

http://localhost:8080/CONTEXT_ROOT/jsp/dynamic_csv.jsp」にアクセスすると、ダウンロードのリンクが表示されて、リンククリック、ボタンクリックでブラウザのダウンロード処理が動きます。

他のTomcatサンプルはこちら


コメント

  • 345 - WEE 2015-07-24 14:31:32
名前: