2000年3月27日星期一

Java生成文件流直接下载汇总

いよいよWEBアプリでExcelファイルをダウンロードします。ファイルをダウンロードするには、ExcelファイルをWEBサーバの適当なディレクトリに置いて、そのファイルにリンクを付ける方法があります。その方法では2つの問題があります。1つはExcelファイルがWEBサーバに残ることです。Excelファイルを定期的に削除する必要が生じます。2つ目はExcelファイルへのリンクURLを直接入力すると、アクセスしてはいけないユーザもアクセスできる可能性があります。ファイルへのアクセスをどうやって制限するか考えなければなりません。

OutputStreamに対して書き込みする方法があります。これだと、物理的にExcelファイルをWEBサーバにおく必要がありません。その方法をサンプルソースを示しながら説明したいと思います。

Servletのファイルダウンロードテクニック

最近はフレームワークを使うことが増えたので、Servletを書く機会が減っていると思います。しかし、Serveltでファイルダウンロードする手順は、ダウンロードの基本になります。まずはServletでのファイルダウンロード手順を見てみましょう。

ファイルダウンロードの手順は至ってシンプルです。

  1. Excelオブジェクトを作成する。
  2. OutputStreamにExcelオブジェクトを書き込む。
  3. OutputStreamをクローズする。
以上です。

以下のサンプルソースでは日本語を扱うちょっとした2つのコツも盛り込んでいます。1つ目は、Excelのセルに日本語をセットするときのコツです。2つ目は、ダウンロードファイルのファイル名に日本語を使うときのコツです。

/*
 * NewServlet.java
 *
 * Created on 2007/04/18, 22:06
 */

import java.io.*;
import java.net.*;

import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

/**
 *
 * @author kiyomiya
 * @version
 */
public class NewServlet extends HttpServlet {
    
    /** Processes requests for both HTTP GET 
     * and POST methods.
     * @param request servlet request
     * @param response servlet response
     */
    protected void processRequest(
            HttpServletRequest request, 
            HttpServletResponse response)
    throws ServletException, IOException {
        
        // 新規EXCELファイルを作成
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet();
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell = row.createCell((short)0);
        
        // 日本語を正しく表示するために文字コードを設定する
        cell.setEncoding(HSSFCell.ENCODING_UTF_16);
        cell.setCellValue("EXCELダウンロード");
        
        // EXCELのコンテントタイプを設定
        response.setContentType("application/msexcel");
        
        // ファイル名に日本語を使うなら、下記のようにエンコードする
        byte[] sjis = "サンプル.xls".getBytes("Shift_JIS");
        String fname = new String(sjis, "ISO8859_1");
        // 英数字なら単純に String fname = "sample.xml" で良い
        
        // ファイル名を設定
        response.setHeader("Content-Disposition", 
            "attachment; filename=" + fname);
        
        OutputStream out = response.getOutputStream();      
        workbook.write(out);
        out.close();
    }
    
    // 
    /** Handles the HTTP GET method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doGet(HttpServletRequest request, 
        HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    /** Handles the HTTP POST method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doPost(HttpServletRequest request, 
        HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    /** Returns a short description of the servlet.
     */
    public String getServletInfo() {
        return "Short description";
    }
    // 
}

Strutsのファイルダウンロードテクニック

代表的なフレームワークであるStrutsでのサンプルも示します。この中でも日本語を扱うちょっとしたコツを含めました。シート名に日本語を使うときのコツです。それにしてもStrutsを使う開発案件が増えましたね...

import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/*
 * NewAction.java
 *
 * Created on 2007/04/19, 22:05
 */

/**
 *
 * @author kiyomiya
 */
public class NewAction extends Action {
    
    public ActionForward execute(
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response)
            throws Exception {
        
        // 新規EXCELファイルを作成
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet();
        
        // シート名に日本語をつけるには、一度シートを
        // create してから名前をセットする
        workbook.setSheetName(0, "日本語のシート名", 
                HSSFWorkbook.ENCODING_UTF_16);
        
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell = row.createCell((short)0);
        cell.setCellValue(true);
        
        // EXCELのコンテントタイプを設定
        response.setContentType("application/msexcel");
        
        // ファイル名を設定
        response.setHeader("Content-Disposition", 
            "attachement; filename=sample.xls");
        
        OutputStream out = response.getOutputStream();
        workbook.write(out);
        out.close();

        return null;
    }
}

JSPでのファイルダウンロードテクニック

最後にJSPのサンプルを示します。以前にServletを一切使わない、JSPだけを使ったWEBアプリの開発案件に携わったことがあります。私の見る限りでは、Servletを使わない方式は決して珍しくないように思います。

<%@page pageEncoding="UTF-8"%>
<%@ page import="org.apache.poi.hssf.usermodel.*" %>
<%@ page import="java.io.OutputStream" %>
<%--
The taglib directive below imports the JSTL library. 
If you uncomment it,you must also add the JSTL library 
to the project. The Add Library... action on Libraries 
node in Projects view can be used to add the JSTL 1.1 library.
--%>
<%--
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 
--%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<% 

// 新規EXCELファイルを作成
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell((short)0);

cell.setCellValue("EXCEL sample");

// EXCELのコンテントタイプを設定
response.setContentType("application/msexcel");

// ファイル名を設定
response.setHeader("Content-Disposition", 
    "attachment; filename=jsp.xls");

OutputStream outs = response.getOutputStream();
workbook.write(outs);
outs.close();

%>

このサンプルは次の環境で動作確認しています。

  • Windows XP Professional SP2
  • Internet Explore 6.0 SP2
  • Excel 2002 SP3
  • JDK 1.6
  • NetBeans IDE 5.5 バンドル版 Tomcat 5.5.17

このサンプルはNetBeans IDE 5.5で作成しました。

没有评论:

发表评论