//SendMessageポインタ
[DllImport("USER32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
//SendMessage文字列
[DllImport("USER32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPTStr)] System.Text.StringBuilder buff);
//EnumChildWindows子クラス取得用
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowProc lpEnumFunc, IntPtr lParam);
//EnumChildWindows子クラス取得用
[DllImport("user32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
//-----------------------------------------
//EnumChildWindowsからのコールバック関数
//-----------------------------------------
public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
//-----------------------------------------
//PostMessage用定数
//-----------------------------------------
//テキスト取得
private const int WM_GETTEXT = 0xD;
//テキスト設定
private const int WM_SETTEXT = 0xC;
//取得テキストの長さ
private const int WM_GETTEXTLENGTH = 0xE;
//--------------------------------------------------------
//引数(ポインタ)の子クラスを取得
//--------------------------------------------------------
public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated) { listHandle.Free(); }
}
return result;
}
//見つけた子クラスハンドルを追記していく
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
list.Add(handle);
// You can modify this to check to see if you want to cancel the operation, then return a null here
return true;
}
private void button2_Click(object sender, EventArgs e)
{
List<IntPtr> list = GetChildWindows(this.Handle);
foreach (IntPtr ptr in list)
{
//取得する文字列の長さを取得
int byteLength = SendMessage(ptr, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero).ToInt32();
System.Text.StringBuilder buff = new System.Text.StringBuilder(byteLength + 1);
//文字列を取得
SendMessage(ptr, WM_GETTEXT, byteLength + 1, buff);
//----------------------------------
//文字列が[LABEL]を含んでいたら
//文字列を変形する
//----------------------------------
if (buff.ToString().ToUpper().Contains("LABEL"))
{
System.Text.StringBuilder sb = new System.Text.StringBuilder("123");
SendMessage(ptr, WM_SETTEXT, 255, sb);
this.Refresh();
}
}
}
犬に関する日記ですが、そのほかにも Tomcat,Apache,Java,VB.NET,Visual Basic, Struts,JSP/Servlet,TomcatとApacheの連携, postgreSQL,Oracleに関する様々なテクニカル 情報を掲載しています。ぜひご活用ください!!
2010年12月12日日曜日
2010年12月7日火曜日
2010年12月2日木曜日
data更新追加削除
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Odbc;
namespace DataGridView
{
public partial class FormDGV : Form
{
OdbcConnectionStringBuilder con_str = null;
OdbcConnection con = null;
OdbcDataAdapter data_adp = null;
OdbcCommandBuilder con_bld = null;
DataTable dt001 = null;
/*
* コンストラクタ
*/
public FormDGV()
{
InitializeComponent();
con_str = new OdbcConnectionStringBuilder("");
con_str.Dsn = "OracleSpring";
con_str["UID"] = "springjoe2";
con_str["PWD"] = "springjoe2";
con = new OdbcConnection(con_str.ConnectionString);
//接続
try
{
con.Open();
data_adp = new OdbcDataAdapter("SELECT * FROM t1", con);
dt001 = new DataTable();
data_adp.Fill(dt001);
con_bld = new OdbcCommandBuilder(data_adp);
data_adp.UpdateCommand = con_bld.GetUpdateCommand();
data_adp.DeleteCommand = con_bld.GetDeleteCommand();
data_adp.InsertCommand = con_bld.GetInsertCommand();
this.bindingSource1.DataSource = dt001;
this.dataGridView1.DataSource = this.bindingSource1;
this.bindingNavigator1.BindingSource = this.bindingSource1;
this.dataGridView1.Refresh();
}
catch (Exception e)
{
con.Close();
MessageBox.Show(e.Message);
}
}
//フォームの位置を保存
private void FormDGV_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.Save();
}
//データテーブルの内容を更新
private void button1_Click(object sender, EventArgs e)
{
OdbcTransaction tr = con.BeginTransaction();
try
{
data_adp.Update(dt001);
tr.Commit();
}
catch
{
tr.Rollback();
}
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Odbc;
namespace DataGridView
{
public partial class FormDGV : Form
{
OdbcConnectionStringBuilder con_str = null;
OdbcConnection con = null;
OdbcDataAdapter data_adp = null;
OdbcCommandBuilder con_bld = null;
DataTable dt001 = null;
/*
* コンストラクタ
*/
public FormDGV()
{
InitializeComponent();
con_str = new OdbcConnectionStringBuilder("");
con_str.Dsn = "OracleSpring";
con_str["UID"] = "springjoe2";
con_str["PWD"] = "springjoe2";
con = new OdbcConnection(con_str.ConnectionString);
//接続
try
{
con.Open();
data_adp = new OdbcDataAdapter("SELECT * FROM t1", con);
dt001 = new DataTable();
data_adp.Fill(dt001);
con_bld = new OdbcCommandBuilder(data_adp);
data_adp.UpdateCommand = con_bld.GetUpdateCommand();
data_adp.DeleteCommand = con_bld.GetDeleteCommand();
data_adp.InsertCommand = con_bld.GetInsertCommand();
this.bindingSource1.DataSource = dt001;
this.dataGridView1.DataSource = this.bindingSource1;
this.bindingNavigator1.BindingSource = this.bindingSource1;
this.dataGridView1.Refresh();
}
catch (Exception e)
{
con.Close();
MessageBox.Show(e.Message);
}
}
//フォームの位置を保存
private void FormDGV_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.Save();
}
//データテーブルの内容を更新
private void button1_Click(object sender, EventArgs e)
{
OdbcTransaction tr = con.BeginTransaction();
try
{
data_adp.Update(dt001);
tr.Commit();
}
catch
{
tr.Rollback();
}
}
}
}
2010年10月15日金曜日
¥と/の関連性(windowsとlinux)
File.separator;
■Linux
filenamenew = filenamenew.replace("¥¥", "/") + "/list.xls";
■Windows
filenamenew = filenamenew.replace("¥¥", "¥¥") + "¥¥list.xls";
※「¥」は小文字の円マーク
■Linux
filenamenew = filenamenew.replace("¥¥", "/") + "/list.xls";
■Windows
filenamenew = filenamenew.replace("¥¥", "¥¥") + "¥¥list.xls";
※「¥」は小文字の円マーク
2010年10月4日月曜日
POIでExcel(エクセル)出力するクラス
POIでExcel(エクセル)出力するクラス
-------------------------------------------------------
【利用方法】
import pois.CreateExcelFile;
CreateExcelFile cef = new CreateExcelFile();
//エクセルファイル開く
final String INVOICE_FILE = "/WEB-INF/mt.xls";
String filePath = getServletContext().getRealPath(INVOICE_FILE);
cef.setInputFile(filePath);
//エクセルファイルデータ入力
cef.setExcelData(3, 1, company_name);
//エクセルファイル保存
String filenamenew = getServletContext().getRealPath("");
filenamenew = filenamenew.replace("\\", "\\\\") + "\\\\list.xls";
cef.setOutputFile(filenamenew);
-------------------------------------------------------
/* 以下CreateExcelFile.java
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pois;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Calendar;
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.poi.poifs.filesystem.POIFSFileSystem;
/**
*
* @author occ
*/
public class CreateExcelFile {
POIFSFileSystem filein;
HSSFWorkbook wb;
HSSFSheet sheet1;
HSSFRow rowd;
HSSFCell celld;
public void setInputFile(String strFileName){
//ファイルを読み込みます。
try{
filein = new POIFSFileSystem(new FileInputStream(strFileName));
//新規ワークブックを作成する
wb = new HSSFWorkbook(filein);
//新規ワークシートを作成する
sheet1 = wb.getSheetAt(0);
}catch(Exception e){
System.out.println(strFileName + "*********************");
}
System.out.println(strFileName);
}
public void setExcelData(int rowNo, int colNo, String sData){
rowd = sheet1.getRow(rowNo);
celld = rowd.getCell(colNo);
celld.setCellValue(sData);
}
public void setExcelData(int rowNo, int colNo, Calendar sData){
rowd = sheet1.getRow(rowNo);
celld = rowd.getCell(colNo);
celld.setCellValue(sData);
}
public void setOutputFile(String strFileName){
try{
FileOutputStream fileOut = new FileOutputStream(strFileName);
wb.write(fileOut);
fileOut.close();
}catch(Exception e){
System.out.println(strFileName + "*********************");
}
System.out.println(strFileName);
}
}
-------------------------------------------------------
【利用方法】
import pois.CreateExcelFile;
CreateExcelFile cef = new CreateExcelFile();
//エクセルファイル開く
final String INVOICE_FILE = "/WEB-INF/mt.xls";
String filePath = getServletContext().getRealPath(INVOICE_FILE);
cef.setInputFile(filePath);
//エクセルファイルデータ入力
cef.setExcelData(3, 1, company_name);
//エクセルファイル保存
String filenamenew = getServletContext().getRealPath("");
filenamenew = filenamenew.replace("\\", "\\\\") + "\\\\list.xls";
cef.setOutputFile(filenamenew);
-------------------------------------------------------
/* 以下CreateExcelFile.java
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pois;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Calendar;
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.poi.poifs.filesystem.POIFSFileSystem;
/**
*
* @author occ
*/
public class CreateExcelFile {
POIFSFileSystem filein;
HSSFWorkbook wb;
HSSFSheet sheet1;
HSSFRow rowd;
HSSFCell celld;
public void setInputFile(String strFileName){
//ファイルを読み込みます。
try{
filein = new POIFSFileSystem(new FileInputStream(strFileName));
//新規ワークブックを作成する
wb = new HSSFWorkbook(filein);
//新規ワークシートを作成する
sheet1 = wb.getSheetAt(0);
}catch(Exception e){
System.out.println(strFileName + "*********************");
}
System.out.println(strFileName);
}
public void setExcelData(int rowNo, int colNo, String sData){
rowd = sheet1.getRow(rowNo);
celld = rowd.getCell(colNo);
celld.setCellValue(sData);
}
public void setExcelData(int rowNo, int colNo, Calendar sData){
rowd = sheet1.getRow(rowNo);
celld = rowd.getCell(colNo);
celld.setCellValue(sData);
}
public void setOutputFile(String strFileName){
try{
FileOutputStream fileOut = new FileOutputStream(strFileName);
wb.write(fileOut);
fileOut.close();
}catch(Exception e){
System.out.println(strFileName + "*********************");
}
System.out.println(strFileName);
}
}
2010年9月23日木曜日
WebアプリケーションでExcelファイルの利用
WebアプリケーションでExcelファイルの利用
「WEB+DB PRESS vol.17」/「Jakartaプロジェクト徹底攻略2 本格活用編」掲載
2003年11月13日
1.はじめに
Javaに関するさまざまなソフトウェアをオープンソースで開発しているJakartaプロジェクトもかなり広まってきて、最近では、プログラムを組むときに、Jakartaプロジェクトのサイトをチェックしてから作り方や作るものを決める、という方も多いのではないでしょうか。
そのJakartaプロジェクトのサブプロジェクトの1つに、Microsoft OfficeのExcel、Wordファイルを読み書きするための、POI注1というライブラリがあります。
現状ではまだ、Excelファイルの読み書きができるようになったばかりですが、プログラムを組むときにExcelが使えると、さまざまな便利な機能を実装することができます。
Webアプリケーションの場合は、データの一括登録やデータ一覧のダウンロード、また、帳票向けの印刷用整形ファイルなどとして、Excelファイルを使うことができるようになります。
本章では、Webシステムを前提として、POIを利用するための基礎知識と活用ノウハウを紹介します。
1.1.POIのバージョン原稿執筆時点のPOIの正式リリース版は1.5.1です。
しかし、これはすでに1年以上前に開発されたバージョンです。といっても、開発が止まっているわけではなく、1.7-devで計算式が使えるようになったり、1.8-devで日本語が扱えるようになったりと、開発版のバージョンは着実に上がっています。現在は、グラフ出力にも対応したバージョン2.0の開発が進められているようです。
余談ですが、1.8-devが出たときに、日本語が使えるようになったということを筆者の日記サイトに書いていたら、POIのサイトからリンクが貼られていました。いまだにリンクされているようです。もっとちゃんとサイトでとりあげようと思いつつ、とりあげないまま今に至ります。
2.Webアプリケーションで利用するための準備
それではまず、WebアプリケーションでPOIを使うための環境を準備することにしましょう。
本稿の内容は、以下の環境で動作を確認しています。以降の解説も、この環境を前提として進めさせていただきます。
OS:Windows 2000
JDK:Java 2 SE 1.4.2
サーブレットコンテナ:Tomcat 4.1.27
OSはWindows 2000を使っていますが、Linuxなど他のOSでも動作すると思います。Excelがインストールされている必要はありません。
対応JDKに関しては、POIのドキュメント中での記述を見つけられませんでしたがJDK 1.4.0での動作を確認しています。サーブレットコンテナはTomcat 4.0.6での動作を確認しています。また記事中サンプルのURLではTomcatへ8080番ポートでアクセスできることを前提としています。
2.1.POIのダウンロードまず、次のURLからPOIをダウンロードします。
http://www.apache.org/dist/jakarta/poi/dev/bin/
本稿では、バージョン2.0の開発版を使用することにします。ダウンロードしたのは、原稿執筆時点で最新の開発版であるpoi-bin-2.0-RC1-20031102.zipです。
開発版とはいえ、簡単な処理では問題なく利用できます。一方正式版でも、「不十分であいまいな」Excelフォーマットを扱うというライブラリの性格上、仕様ともバグともとれる挙動が多く見られます。
開発版にしても正式版にしても、利用範囲での動作確認は必要です。安定性や信頼性が大きく求められる場合には、Windows上でExcelをインストールしてOLEオートメーションを利用するのがやはり一番確実です。
2.2.JSP/サーブレットコンテナの準備以降、筆者が作ったサンプルアプリケーションを使って解説していきます。本誌Webサイトhttp://www.gihyo.co.jp/magazines/wdpress/からサンプルアプリケーションをダウンロードしてご覧いただくとわかりやすいかと思います。なお、誌面の都合でソースコードのすべてを掲載することはできませんのでご了承ください。サンプルアプリケーションのディレクトリ構成は、図1のようになります。
図1 ディレクトリ構成
たとえばC:\java\poiにファイルを置いた場合は、server.xmlにリスト1のようなContextタグを追加します。以降は、ファイルを置いたディレクトリをSAMPLE_HOMEと表します。
リスト1 Contextタグに追加する内容(server.xml)
本稿で作成するサーブレットのマッピングを含んだweb.xmlは、リスト2のようなものになります。
リスト2 本稿で作成するサーブレットのマッピング(web.xml)
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
ExcelGenerateServlet
poisample.ExcelGenerateServlet
StyleServlet
poisample.StyleServlet
RyoshuServlet
poisample.RyoshuServlet
ListServlet
poisample.ListServlet
StyleServlet
/Style
ExcelGenerateServlet
/ExcelGenerate
RyoshuServlet
/Ryoshu
ListServlet
/List
poi-bin-2.0-RC1-20031102.zipを解凍してできたpoi-2.0-RC1-20031102.jarは、WEB-INFディレクトリの下のlibディレクトリに置きます。これによってこのJARファイルは、実行時のクラスパスに自動的に加えられます。また、JSPをコンパイルするときにも利用されます。JSPだけを使うときには、利用するライブラリのJARファイルをこのlibディレクトリに入れておけばクラスパスなどの設定をする必要はありません。サーブレットをコンパイルするときには、クラスパスにこのJARファイルを含んでおく必要があります。
通常のアプリケーションでは、コンパイル時や実行時のクラスパスにこのJARファイルが含まれるようにしてください。本記事では触れていませんが、contribパッケージのクラスを使うときにはpoi-contrib-2.0-RC1-20031102.jarがクラスパスに含まれるようにする必要があります。org.apache.poi.generatorパッケージのクラスやorg.apache.poi.hdf パッケージのクラス、org.apache.poi.hssf.usermodel.HSSFChartクラスを利用するときにはpoi-scratchpad-2.0-RC1-20031102.jarがクラスパスに含まれるようにする必要があります。
3.Excelファイルの読み込み
3.1.Excelファイル読み込みの基本それではとりあえず、Excelファイルを読み込んでみましょう(リスト3)。
リスト3 read.jsp
read.jspをブラウザで読み込む前に、図2のような、A1セルに何かしらの値を記述したExcelファイルを作成してSAMPLE_HOME\xls\simple.xlsに保存します。
図2 読み込みテスト用Excelファイル
その上でhttp://localhost:8080/poi/read.jspを開くと、ExcelファイルのA1セルの値が読み込まれていることがわかります(図3)。
図3 読み込みテストJSPの実行結果
Excel ファイルを読み込むときには、POIFSFileSystemクラスのコンストラクタに読み込み先のInputStreamを指定して生成したオブジェクトを使います(JAR圧縮されたリソースではうまく動かないようです)(1)。
このとき渡したInputStreamオブジェクトは、このコンストラクタ中でしか使われないので、すぐにclose()しても構いません(2)。また、close()を行わないと、読み込んだExcelファイルが上書き保存できなくなることがあります。
エクセルファイルを読み込むには、まずPOIFSFileSystemオブジェクトをコンストラクタに渡してHSSFWorkbookオブジェクトを生成します(3)。このオブジェクトが1つのExcelファイルを表します。
あとは、そこからgetSheetAtメソッドでワークシートをHSSFSheetオブジェクトとして取得して(4)、getRowメソッドでシートの行をHSSFRowオブジェクトとして取得して(5)、getCellメソッドでセルをHSSFCellオブジェクトとして取得します(6)。
セルの値を得るには、取得する値の型によって、getStringCellValueメソッドやgetNumericCellValueメソッドなどを使い分けます(7)。
本稿で使用している主なメソッドは、表1~4のとおりです。
org.apache.poi.hssf.usermodel.HSSFWorkbook
エクセルファイル全体
コンストラクタ HSSFWorkbook(POIFSFileSystem fs) POIFSFileSystemからワークブックオブジェクトを生成する
byte ENCODING_UTF_16 日本語を指定するときの値
void write(OutputStream stream) OutputStreamにワークブックを出力する
HSSFSheet getSheetAt(int index) インデックスを与えてシートを得る
HSSFSheet createSheet() シートを生成する
String setSheetName(int sheet) インデックスを与えてシート名を得る
HSSFCellStyle createCellStyle() セル書式を生成する
HSSFFont createFont() フォントを生成する
HSSFWorkbookの主なメンバ
org.apache.poi.hssf.usermodel.HSSFWorksheet
エクセルシート
HSSFRow getRow(int rownum) 行を取得する
HSSFRow createRow(int rownum) 行を生成する
Iterator rowIterator() 行を走査するイテレータを得る
void setColumnWidth(short column,short width) 行幅を設定する
short getColumnWidth(short column) 列幅を得る
void setDefaultRowHeight(short value) デフォルトの行の高さの設定・取得
short getDefaultRowHeight()
void setDefaultCellWidth(short value) デフォルトの列幅の設定・取得
short getDefaultCellWidth()
HSSFWorksheetの主なメンバ
org.apache.poi.hssf.usermodel.HSSFRow
行
HSSFCell getCell(short cell) セルを取得する
void createCell(short cell) セルを生成する
Iterator cellIterator() セルを走査するイテレータを得る
void setHeight(short value) 行の高さの設定・取得
short getHeight()
HSSFRowの主なメンバ
org.apache.poi.hssf.usermodel.HSSFCell
セル
short ENCODING_UTF_16 日本語を指定するときの値
int CELL_TYPE_STRING 文字列のセルを示す値
int CELL_TYPE_NUMERIC 数値のセルを示す値
int CELL_TYPE_FORMULA 数式のセルを示す値
String getCellFormula() セルの数式を得る
Date getDateCellValue() セルの日付を得る
double getNumericCellValue() セルの数値を得る
String getStringCellValue() セルの文字列を得る
void setCellFormula(String) セルに数式を設定する
void setCellValue(String) セルに文字列を設定する
void setCellStyle(HSSFCellStyle value) セルの書式の設定・取得
HSSFCellStyle getCellStyle()
void setCellType(int value) 値の種類の設定・取得
int getCellType()
void setEncoding(short value) エンコーディングの設定・取得
short getEncoding()
HSSFCellの主なメンバ
3.2.表形式データの読み込み次に、Excelで作成した一覧データを読み込んでみます。業務において、データを一括登録する際のデータ形式としてよく使われるものにCSVがありますが、これは素のままでは、一般の人には編集しにくいものです。結局は、Excelでデータを作成したものをCSVとして保存して使うことが多いと思います。
そうであれば、XLS形式のデータをそのままWebアプリケーション上で読み込めるようにしたほうが手軽です(リスト4)。
リスト4 readlist.jsp
<>
>
ここではまず、図4 のようなExcel ファイルをSAMPLE_HOME\xls\data.xlsとして作成します。D列には「=C3*1.05」という計算式が入力されています。
図4 読み込み用Excelファイル
http://localhost:8080/poi/readlist.jsp(リスト4)を開くと、各データが読み込まれています(図5)。
図5 読み込んだデータの出力
ここでは、データ取得用のメソッドを使い分けて値を取得しています(5)(6)(7)。またD列の計算式のセルは、計算結果をgetNumericCellValueメソッドで(8)、計算式をgetCellFormulaメソッドで取得しています(9)。
またこのプログラムでは、データの各行の取得にHSSFSheet#rowIteratorメソッドで取得したIteratorを利用しています(1)。背景色が黒い行の次からデータを取得して、次に背景色が黒い行が来たら読み込みを終わるようにしています(4)。
背景色の取得では、まずHSSFCell#getCellStyleメソッドでHSSFCellStyleオブジェクトを取得して(2)、getFillForegroundColorメソッドで背景色の色番号を得ています(3)。HSSFCellStyle、HSSFColorのメソッドには、表5、6のようなものがあります。
ここではデータを表示しているだけですが、Excelから読み込んだデータをデータベースに登録するようにすれば、データの一括登録がExcelデータを使って行えるようになります。
org.apache.poi.hssf.usermodel.HSSFCellStyle
セルの書式
short BORDER_DOUBLE 2重線を示す値
short BORDER_THIN 普通の線を示す値
short BORDER_MEDIUM 太線を示す値
void setBorderBottom(short value) 下の罫線の設定・取得
short getBorderBottom()
void setBorderLeft(short value) 左の罫線の設定・取得
short getBorderLeft()
void setBorderRight(short value) 右の罫線の設定・取得
short getBorderRight()
void setBorderTop(short value) 上の罫線の設定・取得
short getBorderTop()
void setDataFormat(short value) 表示形式の設定・取得
short getDataFormat()
void setFillForegroundColor(short value) 塗りつぶし色の設定・取得
short getFillForegroundColor()
HSSFCellStyleの主なメンバ
org.apache.poi.hssf.util.HSSFColor
色
String getHexString() 色の16進数表現を得る
short getIndex() 色番号を得る
short[] getTriplet() RGB値を配列で得る
HSSFColorの主なメンバ
3.3.データ種別の判別先ほどのサンプルでは、読み込むExcelファイルに記述されているデータの形式を決めて処理していました。不定形のデータを読み込むときには、セルのデータ種別を判別する必要があります。(リスト5)
リスト5 readstyle.jsp
<>
>
まず、図6のようなExcelファイルをSAMPLE_HOME\xls\color.xlsとして作成します。C2セルには「=CONCATENATE(B2,"aa")」、C3セルには「=B3*2」という計算式が入力されています。また、いくつかのセルには「塗りつぶしの色」が設定されています。
図6 読み込み用Excelファイル
http://localhost:8080/poi/readstyle.jsp(リスト5)を開くと、各セルが読み込まれています(図7)。
図7 読み込み結果
セルの種別はHSSFCell#getCellTypeメソッドで取得します(2)。
この値がHSSFCell.CELL_TYPE_STRINGのときは文字列です(3)。そのままgetStringCellValue()メソッドで文字列が取得できます。
HSSFCell.CELL_TYPE_NUMERICのときは、数値か日付です(4)。getCellStyleメソッドでHSSFCellStyleオブジェクトを得て、getDataFormatメソッドでデータ形式を得ます(5)。このデータ形式に対してHSSFDateUtil.isInternalDateFormatメソッドで日付であるかどうか判別します(6)。このメソッドがfalseのときは数値形式です。trueのときは日付の形式ですが、その中でも値が22か176のときには日付時刻の形式になっています(7)。
また、HSSFCell.CELL_TYPE_FORMULAのときは計算式です(8)。getCellFormulaメソッドで計算式が得られます。getNumericCellValueメソッドで値が得られますが、Double.isNaNメソッドで数値がどうか判定して、trueのときが数値です(9)。falseのときは文字列などですが、うまく値を取得することができませんでした。
また、このサンプルではHSSFSheet#rowIteratorメソッドやHSSFRow#cellIteratorメソッドを使ってすべてのセルの操作をしていますが(1)、何もない行・セルは無視されてしまっています。実行結果をみるとcellIteratorメソッドで取得したイテレータでは右から左へ処理が進んでいますね。通常の処理ではcellIteratorを使わない方がよさそうです。
3.4.色の判別色の判別には、ちょっと面倒なコードを記述する必要があります。(リスト6)
リスト6 readstyle.jsp(色の判別)
<>
>
改めてhttp://localhost:8080/poi/readstyle.jsp(リスト6)を開くと、各セルの色が読み込まれています(図8)。
図8 色を反映した出力
セルの「塗りつぶしの色」のインデックスは、HSSFCellStyle#getFillForegroundColorメソッドで得ることが出来ます(4)。このインデックスからHSSFColorクラスを継承した、それぞれの色に対応したクラスのオブジェクトを取得するには、サンプル中のgetColorFromIndexメソッドのような処理を行う必要があります(1)。このサンプルでは、必要な色しか判定していませんが、どんな色にも対応できるようにするためには、HSSFColorクラスを継承した50個弱の色クラスについて判定を行う必要があります。どのような色のクラスがあるかはPOIに付属のドキュメントをご覧ください。
また、セルのフォントをあらわすHSSFFontオブジェクトを得るには、HSSFCellStyle#getFontIndexメソッドで得たインデックスをHSSFWorkbook#getFontAtメソッドに渡します(5)。
このサンプルでは、全セルの処理をforループで行っていますが(2)(3)、行に関してはHSSFSheet#getLastRowNumメソッドの戻り値が示す行番号まで処理をする必要があるのに対して、セルに関してはHSSFRow#getLastCellNumメソッドの戻り値が示すセル番号の直前までしか処理をする必要がないので注意が必要です。
3.5.Excelデータのアップロード先ほどの例では静的なファイルを直接指定して読み込んでみましたが、Webアプリケーションでは、ExcelファイルをHTMLフォームからアップロードすることが多いと思います。
Javaには標準ではファイルアップロードの機能が用意されていないので、これまたJakartaプロジェクトの成果物であるCommons FileUploadを使って、この機能を実現することにしましょう。
FileUploadのダウンロードは次に示すJakartaのダウンロードサイトから行います。
http://jakarta.apache.org/site/binindex.cgi
「Commons FileUpload」の「1.0 zip」をクリックし、commons-fileupload-1.0.zipをダウンロードします。また、FileUploadはBeanUtilsを利用するので,同じくJakartaのダウンロードサイトで「Commons Beanutils」の「1.6.1 zip」をクリック、commons-beanutils-1.6.1.zipをダウンロードします。
それぞれ解凍後に生成されるcommons-fileupload-1.0.jarとcommons-beanutils.jarをWEB-INFディレクトリの下のlibディレクトリにコピーします。今回はJSPからの利用だけなので、とくにクラスパスの設定などは必要ありません。
アップロード用のフォームは、リスト7のようなものを用意します。
ファイルの受け取り側(リスト8)は、ファイル読み込みプログラム(リスト4)の読み込み部分を、アップロードデータを取得するように変更したものです。
リスト8 readlist.jsp(アップロード対応版)
<>
>
Javaでは入力先が変わっても、処理が同じであれば、入力先だけを変えればよいので便利ですね。
HTMLフォーム(リスト7、図9)で先ほど読み込んだファイル(図4)を指定します。送信ボタンを押すと、先ほどと同じ画面(図5)が表示されて、データが読み込まれていることがわかります。
リスト7 upload.html
ファイル:
図9 ファイル指定画面
ファイルアップロードに関する詳しい説明はここでは割愛しますが、DiskFileUpload#parseRequestメソッドでFileItemオブジェクトなどが格納されたListオブジェクトを取得して(1)、その中のFileItemオブジェクトからgetInputStreamメソッドでInputStreamオブジェクトを取得して処理をする(2)という流れになっています。
4.Excelファイルの作成
次に、Excelファイルの生成をしてみましょう。まず、単純なファイルを生成してみます(リスト9)。
リスト9 generate.jsp
生成しました
http://localhost:8080/poi/generate.jspを開くと、ブラウザ画面に図10のような表示が出て、SAMPLE_HOME\xls\generated.xlsとして図11のようなExcelファイルが生成されているはずです。
図10 生成後のメッセージ
図11 生成されたExcelデータ
Excelファイルの作成を行うにはまず、HSSFWorkbookオブジェクトを生成します(1)。それからcreateSheetメソッドでワークシートとしてHSSFSheetオブジェクトを生成(2)、createRowメソッドで行としてHSSFRowオブジェクトを作成(3)、そしてcreateCellメソッドでセルとしてHSSFCellオブジェクトを作成することになります(4)。
あとはそのHSSFCellオブジェクトにsetCellValueメソッドで値を設定することになります(6)。setCellValueメソッドはStringやdoubleを引数として受け取るものがそれぞれ用意されているので、あまり型を意識することはありません。
2バイト文字を設定する場合には、setEncodingメソッドでセルのエンコーディングとしてHSSFCell.ENCODING_UTF_16を指定しておく必要があります(5)。
計算式を設定する場合にはsetCellFormulaメソッドを使います(7)。このとき、「=」をつける必要はないので注意してください(セルの計算自体は、Excelで開いたときに行われるので、直後にgetNumericCellValueメソッドなどで計算結果を得ることはできません)。
値の設定などが終わったら、HSSFWorkbookオブジェクトのwriteメソッドを呼び出して、OutputStreamに出力します(8)。ここではファイルに書き込むのでFileOutputStreamオブジェクトを引数として渡しています。
4.1.動的Excelファイルのダウンロードそれでは次に、Webアプリケーションらしく、動的に生成したExcelファイルをブラウザからダウンロードできるようにしてみましょう。Excelファイルのようなバイナリデータの生成をJSPで行うことはできないため、サーブレットを使います(リスト10)。
リスト10 ExcelGenerateServlet.java
package poisample;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.poi.hssf.usermodel.*;
public class ExcelGenerateServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
wb.setSheetName(0,
"ダウンロード",HSSFWorkbook.ENCODING_UTF_16);
//文字列の書き込み
HSSFCell cell = sheet.createRow(0).createCell((short)1);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue("ダウンロードサンプル");
//送信
response.setHeader("Content-Disposition",
"attachment;filename=download.xls");
response.setContentType("application/vnd.ms-excel");
wb.write(response.getOutputStream());
}
}
このサーブレットは、web.xmlに記述したマッピングによってhttp://localhost:8080/poi/ExcelGenereteにアクセスすることで実行されるようになっています。アクセスすると、ダウンロードが始まります(図12)。
図12 「ファイルのダウンロード」ダイアログ
保存すると、図13のようなExcelファイルが生成されています。
図13 生成されたExcelファイル
ダウンロード時のContentTypeは「application/vnd.ms-excel」としています(1)。また、初期ファイル名を指定するためにContent-Dispositionヘッダでファイル名を指定しています(2)。
サーブレットからの送信は、HSSFWorkbookオブジェクトのwriteメソッドにHttpServletResponse#getOutputStreamメソッドの戻り値を渡すことで行われています(3)。
4.2.書式の設定単純な出力ができるようになったので、次はさまざまな書式を設定してみます(リスト11)。
リスト11 StyleServlet.java
package poisample;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
public class StyleServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
wb.setSheetName(0,"書式",HSSFWorkbook.ENCODING_UTF_16);
//セル幅
sheet.setColumnWidth((short)0,(short)5120);//140ピクセル
sheet.setColumnWidth((short)1,(short)7680);//210ピクセル
sheet.setColumnWidth((short)2,(short)7680);//210ピクセル
HSSFRow row;
HSSFCell cell;
HSSFCellStyle style;
HSSFFont font;
//背景・罫線
row = sheet.createRow((short)1);
cell = row.createCell((short)0);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue("背景色");
style = wb.createCellStyle();
style.setFillForegroundColor(HSSFColor.BRIGHT_GREEN.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
style.setBorderTop(HSSFCellStyle.BORDER_DOUBLE);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
cell.setCellStyle(style);
//日付
cell = row.createCell((short)1);
cell.setCellValue(new java.util.Date());
style = wb.createCellStyle();
style.setDataFormat((short)22);
cell.setCellStyle(style);
//フォント
row = sheet.createRow((short)2);
String[] fonts = {
"MS Pゴシック","MS P明朝","HG創英角ポップ体"};
for(short col = 0; col < 3; ++col){
cell = row.createCell(col);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue(fonts[col]);
font = wb.createFont();
font.setFontName(fonts[col]);
font.setFontHeight((short)320);//16ポイント
style = wb.createCellStyle();
style.setFont(font);
cell.setCellStyle(style);
}
//送信
response.setHeader("Content-Disposition",
"attachment;filename=style.xls");
response.setContentType("application/vnd.ms-excel");
wb.write(response.getOutputStream());
}
}
このサーブレットは/StyleというURLにマッピングするようにweb.xmlに記述しています。http://localhost:8080/poi/Styleにアクセスすることでサーブレットによって生成されたExcelファイルのダウンロードが始まります。保存すると図14のようなファイルになります。
図14 生成されたExcelファイル
このサンプルでは、セル幅・背景色・罫線・日付・フォントサイズ・フォントの種類を設定しています。
セル幅は、HSSFSheetオブジェクトのsetColumnWidthメソッドで指定します(1)。このとき指定する数値は2560が70ピクセルにあたります。
セルの書式はHSSFCellStyleクラスが管理します。
日付を設定する際に、setDataFormatメソッドで日付のフォーマットを指定する必要があります(2)。日付のフォーマットとして引数に渡すことができる値には表7のようなものがあります。
フォントはHSSFFontクラスで管理しています(表8)。フォントサイズはsetFontHeightメソッドで指定しますが(4)、このとき指定する数値は20が1ポイントにあたります。
フォントの種類はsetFontNameメソッドで指定します(3)。図14を見ると、MSゴシックとMS明朝はうまく設定できているのですが、HG創英角ポップ体はうまく設定できていません。MSゴシックとMS明朝以外の日本語名のフォントはうまく設定できないようです。
日付フォーマット
14 2002/11/2
31 2002年11月2日
55 2002年11月
56 11月2日
57 H14.11.2
58 平成14年11月2日
177 11/2
22 2002/11/2 0:00
176 2002/11/2 12:00 AM
org.apache.poi.hssf.usermodel.HSSFFont
フォント
short BOLDWEIGHT_BOLD ボールド体を示す値
void setBoldweight(short value) 太さの設定・取得
short getBoldweight()
void setFontHeight(short value) フォントサイズの設定・取得
short getFontHeight()
void setFontName(String value) フォント名の設定・取得
String getFontName()
void setStrikeout(boolean value) 打ち消し線の設定・取得
boolean getStrikeout()
void setUnderline(boolean value) 下線の設定・取得
boolean getUnderline()
HSSFFontの主なメンバ
4.3.書式テンプレートプログラムでいちいち書式を設定するのも面倒なので、書式を指定したファイル(図15)をあらかじめ用意するようにしてみましょう(リスト12)。
リスト12 RyoshuServlet.java
package poisample;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.*;
public class RyoshuServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String path = getServletContext().getRealPath(
"/xls/ryoshu-template.xls");
InputStream is = new FileInputStream(path);
POIFSFileSystem fs = new POIFSFileSystem(is);
is.close();
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFCell cell;
//宛名
cell = sheet.getRow((short)3).getCell((short)1);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue("評論工務店様");
//日付
cell = sheet.getRow((short)2).getCell((short)5);
cell.setCellValue(new java.util.Date());
//金額
cell = sheet.getRow((short)7).getCell((short)1);;
cell.setCellValue(15000);
//送信
response.setHeader("Content-Disposition",
"attachment;filename=ryoshu.xls");
response.setContentType("application/vnd.ms-excel");
wb.write(response.getOutputStream());
}
}
図15 リスト表示用のテンプレート
図15のファイルは、あらかじめSAMPLE_HOME\xls\ryoshu-template.xlsとして用意しておきます。この中の宛名・日付・金額の部分をサーブレットで変更して送信するようにします。
このサーブレットは/RyoshuというURLにマッピングするようにweb.xmlに記述しています。http://localhost:8080/poi/Ryoshuにアクセスすることでサーブレットによって生成されたExcelファイルのダウンロードが始まります。保存すると図16のようなファイルになります。
図16 作成されたファイル
このようにすると、Excelを書式エディタとして使うことができます。PDFの場合は柔軟なレイアウトができますが、PDF作成ツールは普及率が低く、また、操作も煩雑になりがちです。その点、Excelはレイアウトの制限は大きいのですが、普及率も高くレイアウト作成の操作も簡単です。
また、テンプレートファイルで用意しておけば、日本語名のフォントなどPOIでは扱えないものも問題なく扱えるようです。簡単な印刷フォームとして利用すると便利なのではないでしょうか。
4.4.書式付リストの出力最後に、書式テンプレートを元にリストを出力するサンプルをご紹介します(リスト13)。あらかじめ、図17のようなファイルを用意しておきます。
リスト13 ListServlet.java
package poisample;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.*;
public class ListServlet extends HttpServlet {
String[][] sampledata = {
{"なかやま","モツ鍋","大橋","4000"},
{"ショッパイヤ","ブラジル料理","西通り","3000"},
{"九ちゃん","ラーメン","大宰府","500"}};
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String path = getServletContext().getRealPath("/list-template2.xls");
InputStream is = new FileInputStream(path);
POIFSFileSystem fs = new POIFSFileSystem(is);
is.close();
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
//スタイル取得
HSSFCellStyle[] styles = new HSSFCellStyle[sampledata[0].length];
HSSFRow row = sheet.getRow((short)3);
for(short i = 0; i < styles.length; ++i){
styles[i] = row.getCell(i).getCellStyle();
}
for(int i = 0; i < sampledata.length; ++i){
//行作成
if(i > 0){
//2行目以降
sheet.shiftRows(i + 3,i + 3 ,1);
row = sheet.createRow(i + 3);
for(short j = 0; j < sampledata[i].length; ++j) row.createCell(j);
}
else{
//最初のデータ
row = sheet.getRow(i + 3);
}
for(short j = 0; j < sampledata[i].length; ++j){
HSSFCell cell = row.getCell(j);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellStyle(styles[j]);
if(j < 3){
cell.setCellValue(sampledata[i][j]);
}else{
cell.setCellValue(Integer.parseInt(sampledata[i][j]));
}
}
}
//平均の計算式
row = sheet.getRow(sampledata.length + 3);
if(row != null){
HSSFCell cell = row.getCell((short)3);
if(cell != null){
String f = "average(d4:d" + (3 + sampledata.length) + ")";
cell.setCellFormula(f);
}
}
//送信
response.setHeader("Content-Disposition", "attachment;filename=list.xls");
response.setContentType("application/vnd.ms-excel");
wb.write(response.getOutputStream());
}
}
図17 テンプレート用のExcelファイル
図17のファイルを、SAMPLE_HOME\xls\listtemplate.xlsとして用意します。
このサーブレットは/ListというURLにマッピングするようにweb.xmlに記述しています。http://localhost:8080/poi/Listにアクセスすることでサーブレットによって生成されたExcelファイルのダウンロードが始まります。保存すると図18のようなファイルになります。
図18 生成されたExcelファイル
書式テンプレートの4行めの書式を元に、各行が書式設定されています。
行を挿入するメソッドは無いようなので、HSSFSheet#shiftRowsメソッドで下部の行をシフトさせています(1)。このとき、こうやって行をシフトさせても「=sum(d3:d4)」など計算式で示されているセルは変わらないので注意が必要です。
5.まとめ
以上のように、Excelファイルを扱うことができれば、アプリケーションの幅も広がります。また、今回は試していませんが、POI 2.0からはグラフを扱うこともできるようになるようです。グラフの扱いがうまくできるようになれば、また、POIを使った応用がさらにいろいろ考えられそうです。
--------------------------------------------------------------------------------
Copyright (c) 2001-2004 Naoki Kishida All Rights Reserved.
http://www.fk.urban.ne.jp/home/kishida/
「WEB+DB PRESS vol.17」/「Jakartaプロジェクト徹底攻略2 本格活用編」掲載
2003年11月13日
1.はじめに
Javaに関するさまざまなソフトウェアをオープンソースで開発しているJakartaプロジェクトもかなり広まってきて、最近では、プログラムを組むときに、Jakartaプロジェクトのサイトをチェックしてから作り方や作るものを決める、という方も多いのではないでしょうか。
そのJakartaプロジェクトのサブプロジェクトの1つに、Microsoft OfficeのExcel、Wordファイルを読み書きするための、POI注1というライブラリがあります。
現状ではまだ、Excelファイルの読み書きができるようになったばかりですが、プログラムを組むときにExcelが使えると、さまざまな便利な機能を実装することができます。
Webアプリケーションの場合は、データの一括登録やデータ一覧のダウンロード、また、帳票向けの印刷用整形ファイルなどとして、Excelファイルを使うことができるようになります。
本章では、Webシステムを前提として、POIを利用するための基礎知識と活用ノウハウを紹介します。
1.1.POIのバージョン原稿執筆時点のPOIの正式リリース版は1.5.1です。
しかし、これはすでに1年以上前に開発されたバージョンです。といっても、開発が止まっているわけではなく、1.7-devで計算式が使えるようになったり、1.8-devで日本語が扱えるようになったりと、開発版のバージョンは着実に上がっています。現在は、グラフ出力にも対応したバージョン2.0の開発が進められているようです。
余談ですが、1.8-devが出たときに、日本語が使えるようになったということを筆者の日記サイトに書いていたら、POIのサイトからリンクが貼られていました。いまだにリンクされているようです。もっとちゃんとサイトでとりあげようと思いつつ、とりあげないまま今に至ります。
2.Webアプリケーションで利用するための準備
それではまず、WebアプリケーションでPOIを使うための環境を準備することにしましょう。
本稿の内容は、以下の環境で動作を確認しています。以降の解説も、この環境を前提として進めさせていただきます。
OS:Windows 2000
JDK:Java 2 SE 1.4.2
サーブレットコンテナ:Tomcat 4.1.27
OSはWindows 2000を使っていますが、Linuxなど他のOSでも動作すると思います。Excelがインストールされている必要はありません。
対応JDKに関しては、POIのドキュメント中での記述を見つけられませんでしたがJDK 1.4.0での動作を確認しています。サーブレットコンテナはTomcat 4.0.6での動作を確認しています。また記事中サンプルのURLではTomcatへ8080番ポートでアクセスできることを前提としています。
2.1.POIのダウンロードまず、次のURLからPOIをダウンロードします。
http://www.apache.org/dist/jakarta/poi/dev/bin/
本稿では、バージョン2.0の開発版を使用することにします。ダウンロードしたのは、原稿執筆時点で最新の開発版であるpoi-bin-2.0-RC1-20031102.zipです。
開発版とはいえ、簡単な処理では問題なく利用できます。一方正式版でも、「不十分であいまいな」Excelフォーマットを扱うというライブラリの性格上、仕様ともバグともとれる挙動が多く見られます。
開発版にしても正式版にしても、利用範囲での動作確認は必要です。安定性や信頼性が大きく求められる場合には、Windows上でExcelをインストールしてOLEオートメーションを利用するのがやはり一番確実です。
2.2.JSP/サーブレットコンテナの準備以降、筆者が作ったサンプルアプリケーションを使って解説していきます。本誌Webサイトhttp://www.gihyo.co.jp/magazines/wdpress/からサンプルアプリケーションをダウンロードしてご覧いただくとわかりやすいかと思います。なお、誌面の都合でソースコードのすべてを掲載することはできませんのでご了承ください。サンプルアプリケーションのディレクトリ構成は、図1のようになります。
図1 ディレクトリ構成
たとえばC:\java\poiにファイルを置いた場合は、server.xmlにリスト1のようなContextタグを追加します。以降は、ファイルを置いたディレクトリをSAMPLE_HOMEと表します。
リスト1 Contextタグに追加する内容(server.xml)
本稿で作成するサーブレットのマッピングを含んだweb.xmlは、リスト2のようなものになります。
リスト2 本稿で作成するサーブレットのマッピング(web.xml)
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
poi-bin-2.0-RC1-20031102.zipを解凍してできたpoi-2.0-RC1-20031102.jarは、WEB-INFディレクトリの下のlibディレクトリに置きます。これによってこのJARファイルは、実行時のクラスパスに自動的に加えられます。また、JSPをコンパイルするときにも利用されます。JSPだけを使うときには、利用するライブラリのJARファイルをこのlibディレクトリに入れておけばクラスパスなどの設定をする必要はありません。サーブレットをコンパイルするときには、クラスパスにこのJARファイルを含んでおく必要があります。
通常のアプリケーションでは、コンパイル時や実行時のクラスパスにこのJARファイルが含まれるようにしてください。本記事では触れていませんが、contribパッケージのクラスを使うときにはpoi-contrib-2.0-RC1-20031102.jarがクラスパスに含まれるようにする必要があります。org.apache.poi.generatorパッケージのクラスやorg.apache.poi.hdf パッケージのクラス、org.apache.poi.hssf.usermodel.HSSFChartクラスを利用するときにはpoi-scratchpad-2.0-RC1-20031102.jarがクラスパスに含まれるようにする必要があります。
3.Excelファイルの読み込み
3.1.Excelファイル読み込みの基本それではとりあえず、Excelファイルを読み込んでみましょう(リスト3)。
リスト3 read.jsp
とりあえず読み込み
read.jspをブラウザで読み込む前に、図2のような、A1セルに何かしらの値を記述したExcelファイルを作成してSAMPLE_HOME\xls\simple.xlsに保存します。
図2 読み込みテスト用Excelファイル
その上でhttp://localhost:8080/poi/read.jspを開くと、ExcelファイルのA1セルの値が読み込まれていることがわかります(図3)。
図3 読み込みテストJSPの実行結果
Excel ファイルを読み込むときには、POIFSFileSystemクラスのコンストラクタに読み込み先のInputStreamを指定して生成したオブジェクトを使います(JAR圧縮されたリソースではうまく動かないようです)(1)。
このとき渡したInputStreamオブジェクトは、このコンストラクタ中でしか使われないので、すぐにclose()しても構いません(2)。また、close()を行わないと、読み込んだExcelファイルが上書き保存できなくなることがあります。
エクセルファイルを読み込むには、まずPOIFSFileSystemオブジェクトをコンストラクタに渡してHSSFWorkbookオブジェクトを生成します(3)。このオブジェクトが1つのExcelファイルを表します。
あとは、そこからgetSheetAtメソッドでワークシートをHSSFSheetオブジェクトとして取得して(4)、getRowメソッドでシートの行をHSSFRowオブジェクトとして取得して(5)、getCellメソッドでセルをHSSFCellオブジェクトとして取得します(6)。
セルの値を得るには、取得する値の型によって、getStringCellValueメソッドやgetNumericCellValueメソッドなどを使い分けます(7)。
本稿で使用している主なメソッドは、表1~4のとおりです。
org.apache.poi.hssf.usermodel.HSSFWorkbook
エクセルファイル全体
コンストラクタ HSSFWorkbook(POIFSFileSystem fs) POIFSFileSystemからワークブックオブジェクトを生成する
byte ENCODING_UTF_16 日本語を指定するときの値
void write(OutputStream stream) OutputStreamにワークブックを出力する
HSSFSheet getSheetAt(int index) インデックスを与えてシートを得る
HSSFSheet createSheet() シートを生成する
String setSheetName(int sheet) インデックスを与えてシート名を得る
HSSFCellStyle createCellStyle() セル書式を生成する
HSSFFont createFont() フォントを生成する
HSSFWorkbookの主なメンバ
org.apache.poi.hssf.usermodel.HSSFWorksheet
エクセルシート
HSSFRow getRow(int rownum) 行を取得する
HSSFRow createRow(int rownum) 行を生成する
Iterator rowIterator() 行を走査するイテレータを得る
void setColumnWidth(short column,short width) 行幅を設定する
short getColumnWidth(short column) 列幅を得る
void setDefaultRowHeight(short value) デフォルトの行の高さの設定・取得
short getDefaultRowHeight()
void setDefaultCellWidth(short value) デフォルトの列幅の設定・取得
short getDefaultCellWidth()
HSSFWorksheetの主なメンバ
org.apache.poi.hssf.usermodel.HSSFRow
行
HSSFCell getCell(short cell) セルを取得する
void createCell(short cell) セルを生成する
Iterator cellIterator() セルを走査するイテレータを得る
void setHeight(short value) 行の高さの設定・取得
short getHeight()
HSSFRowの主なメンバ
org.apache.poi.hssf.usermodel.HSSFCell
セル
short ENCODING_UTF_16 日本語を指定するときの値
int CELL_TYPE_STRING 文字列のセルを示す値
int CELL_TYPE_NUMERIC 数値のセルを示す値
int CELL_TYPE_FORMULA 数式のセルを示す値
String getCellFormula() セルの数式を得る
Date getDateCellValue() セルの日付を得る
double getNumericCellValue() セルの数値を得る
String getStringCellValue() セルの文字列を得る
void setCellFormula(String) セルに数式を設定する
void setCellValue(String) セルに文字列を設定する
void setCellStyle(HSSFCellStyle value) セルの書式の設定・取得
HSSFCellStyle getCellStyle()
void setCellType(int value) 値の種類の設定・取得
int getCellType()
void setEncoding(short value) エンコーディングの設定・取得
short getEncoding()
HSSFCellの主なメンバ
3.2.表形式データの読み込み次に、Excelで作成した一覧データを読み込んでみます。業務において、データを一括登録する際のデータ形式としてよく使われるものにCSVがありますが、これは素のままでは、一般の人には編集しにくいものです。結局は、Excelでデータを作成したものをCSVとして保存して使うことが多いと思います。
そうであれば、XLS形式のデータをそのままWebアプリケーション上で読み込めるようにしたほうが手軽です(リスト4)。
リスト4 readlist.jsp
データ読み込み
ここではまず、図4 のようなExcel ファイルをSAMPLE_HOME\xls\data.xlsとして作成します。D列には「=C3*1.05」という計算式が入力されています。
図4 読み込み用Excelファイル
http://localhost:8080/poi/readlist.jsp(リスト4)を開くと、各データが読み込まれています(図5)。
図5 読み込んだデータの出力
ここでは、データ取得用のメソッドを使い分けて値を取得しています(5)(6)(7)。またD列の計算式のセルは、計算結果をgetNumericCellValueメソッドで(8)、計算式をgetCellFormulaメソッドで取得しています(9)。
またこのプログラムでは、データの各行の取得にHSSFSheet#rowIteratorメソッドで取得したIteratorを利用しています(1)。背景色が黒い行の次からデータを取得して、次に背景色が黒い行が来たら読み込みを終わるようにしています(4)。
背景色の取得では、まずHSSFCell#getCellStyleメソッドでHSSFCellStyleオブジェクトを取得して(2)、getFillForegroundColorメソッドで背景色の色番号を得ています(3)。HSSFCellStyle、HSSFColorのメソッドには、表5、6のようなものがあります。
ここではデータを表示しているだけですが、Excelから読み込んだデータをデータベースに登録するようにすれば、データの一括登録がExcelデータを使って行えるようになります。
org.apache.poi.hssf.usermodel.HSSFCellStyle
セルの書式
short BORDER_DOUBLE 2重線を示す値
short BORDER_THIN 普通の線を示す値
short BORDER_MEDIUM 太線を示す値
void setBorderBottom(short value) 下の罫線の設定・取得
short getBorderBottom()
void setBorderLeft(short value) 左の罫線の設定・取得
short getBorderLeft()
void setBorderRight(short value) 右の罫線の設定・取得
short getBorderRight()
void setBorderTop(short value) 上の罫線の設定・取得
short getBorderTop()
void setDataFormat(short value) 表示形式の設定・取得
short getDataFormat()
void setFillForegroundColor(short value) 塗りつぶし色の設定・取得
short getFillForegroundColor()
HSSFCellStyleの主なメンバ
org.apache.poi.hssf.util.HSSFColor
色
String getHexString() 色の16進数表現を得る
short getIndex() 色番号を得る
short[] getTriplet() RGB値を配列で得る
HSSFColorの主なメンバ
3.3.データ種別の判別先ほどのサンプルでは、読み込むExcelファイルに記述されているデータの形式を決めて処理していました。不定形のデータを読み込むときには、セルのデータ種別を判別する必要があります。(リスト5)
リスト5 readstyle.jsp
データ種別
まず、図6のようなExcelファイルをSAMPLE_HOME\xls\color.xlsとして作成します。C2セルには「=CONCATENATE(B2,"aa")」、C3セルには「=B3*2」という計算式が入力されています。また、いくつかのセルには「塗りつぶしの色」が設定されています。
図6 読み込み用Excelファイル
http://localhost:8080/poi/readstyle.jsp(リスト5)を開くと、各セルが読み込まれています(図7)。
図7 読み込み結果
セルの種別はHSSFCell#getCellTypeメソッドで取得します(2)。
この値がHSSFCell.CELL_TYPE_STRINGのときは文字列です(3)。そのままgetStringCellValue()メソッドで文字列が取得できます。
HSSFCell.CELL_TYPE_NUMERICのときは、数値か日付です(4)。getCellStyleメソッドでHSSFCellStyleオブジェクトを得て、getDataFormatメソッドでデータ形式を得ます(5)。このデータ形式に対してHSSFDateUtil.isInternalDateFormatメソッドで日付であるかどうか判別します(6)。このメソッドがfalseのときは数値形式です。trueのときは日付の形式ですが、その中でも値が22か176のときには日付時刻の形式になっています(7)。
また、HSSFCell.CELL_TYPE_FORMULAのときは計算式です(8)。getCellFormulaメソッドで計算式が得られます。getNumericCellValueメソッドで値が得られますが、Double.isNaNメソッドで数値がどうか判定して、trueのときが数値です(9)。falseのときは文字列などですが、うまく値を取得することができませんでした。
また、このサンプルではHSSFSheet#rowIteratorメソッドやHSSFRow#cellIteratorメソッドを使ってすべてのセルの操作をしていますが(1)、何もない行・セルは無視されてしまっています。実行結果をみるとcellIteratorメソッドで取得したイテレータでは右から左へ処理が進んでいますね。通常の処理ではcellIteratorを使わない方がよさそうです。
3.4.色の判別色の判別には、ちょっと面倒なコードを記述する必要があります。(リスト6)
リスト6 readstyle.jsp(色の判別)
データ種別
改めてhttp://localhost:8080/poi/readstyle.jsp(リスト6)を開くと、各セルの色が読み込まれています(図8)。
図8 色を反映した出力
セルの「塗りつぶしの色」のインデックスは、HSSFCellStyle#getFillForegroundColorメソッドで得ることが出来ます(4)。このインデックスからHSSFColorクラスを継承した、それぞれの色に対応したクラスのオブジェクトを取得するには、サンプル中のgetColorFromIndexメソッドのような処理を行う必要があります(1)。このサンプルでは、必要な色しか判定していませんが、どんな色にも対応できるようにするためには、HSSFColorクラスを継承した50個弱の色クラスについて判定を行う必要があります。どのような色のクラスがあるかはPOIに付属のドキュメントをご覧ください。
また、セルのフォントをあらわすHSSFFontオブジェクトを得るには、HSSFCellStyle#getFontIndexメソッドで得たインデックスをHSSFWorkbook#getFontAtメソッドに渡します(5)。
このサンプルでは、全セルの処理をforループで行っていますが(2)(3)、行に関してはHSSFSheet#getLastRowNumメソッドの戻り値が示す行番号まで処理をする必要があるのに対して、セルに関してはHSSFRow#getLastCellNumメソッドの戻り値が示すセル番号の直前までしか処理をする必要がないので注意が必要です。
3.5.Excelデータのアップロード先ほどの例では静的なファイルを直接指定して読み込んでみましたが、Webアプリケーションでは、ExcelファイルをHTMLフォームからアップロードすることが多いと思います。
Javaには標準ではファイルアップロードの機能が用意されていないので、これまたJakartaプロジェクトの成果物であるCommons FileUploadを使って、この機能を実現することにしましょう。
FileUploadのダウンロードは次に示すJakartaのダウンロードサイトから行います。
http://jakarta.apache.org/site/binindex.cgi
「Commons FileUpload」の「1.0 zip」をクリックし、commons-fileupload-1.0.zipをダウンロードします。また、FileUploadはBeanUtilsを利用するので,同じくJakartaのダウンロードサイトで「Commons Beanutils」の「1.6.1 zip」をクリック、commons-beanutils-1.6.1.zipをダウンロードします。
それぞれ解凍後に生成されるcommons-fileupload-1.0.jarとcommons-beanutils.jarをWEB-INFディレクトリの下のlibディレクトリにコピーします。今回はJSPからの利用だけなので、とくにクラスパスの設定などは必要ありません。
アップロード用のフォームは、リスト7のようなものを用意します。
ファイルの受け取り側(リスト8)は、ファイル読み込みプログラム(リスト4)の読み込み部分を、アップロードデータを取得するように変更したものです。
リスト8 readlist.jsp(アップロード対応版)
データ読み込み
Javaでは入力先が変わっても、処理が同じであれば、入力先だけを変えればよいので便利ですね。
HTMLフォーム(リスト7、図9)で先ほど読み込んだファイル(図4)を指定します。送信ボタンを押すと、先ほどと同じ画面(図5)が表示されて、データが読み込まれていることがわかります。
リスト7 upload.html
アップロード
ファイル:
図9 ファイル指定画面
ファイルアップロードに関する詳しい説明はここでは割愛しますが、DiskFileUpload#parseRequestメソッドでFileItemオブジェクトなどが格納されたListオブジェクトを取得して(1)、その中のFileItemオブジェクトからgetInputStreamメソッドでInputStreamオブジェクトを取得して処理をする(2)という流れになっています。
4.Excelファイルの作成
次に、Excelファイルの生成をしてみましょう。まず、単純なファイルを生成してみます(リスト9)。
リスト9 generate.jsp
Excel生成
生成しました
http://localhost:8080/poi/generate.jspを開くと、ブラウザ画面に図10のような表示が出て、SAMPLE_HOME\xls\generated.xlsとして図11のようなExcelファイルが生成されているはずです。
図10 生成後のメッセージ
図11 生成されたExcelデータ
Excelファイルの作成を行うにはまず、HSSFWorkbookオブジェクトを生成します(1)。それからcreateSheetメソッドでワークシートとしてHSSFSheetオブジェクトを生成(2)、createRowメソッドで行としてHSSFRowオブジェクトを作成(3)、そしてcreateCellメソッドでセルとしてHSSFCellオブジェクトを作成することになります(4)。
あとはそのHSSFCellオブジェクトにsetCellValueメソッドで値を設定することになります(6)。setCellValueメソッドはStringやdoubleを引数として受け取るものがそれぞれ用意されているので、あまり型を意識することはありません。
2バイト文字を設定する場合には、setEncodingメソッドでセルのエンコーディングとしてHSSFCell.ENCODING_UTF_16を指定しておく必要があります(5)。
計算式を設定する場合にはsetCellFormulaメソッドを使います(7)。このとき、「=」をつける必要はないので注意してください(セルの計算自体は、Excelで開いたときに行われるので、直後にgetNumericCellValueメソッドなどで計算結果を得ることはできません)。
値の設定などが終わったら、HSSFWorkbookオブジェクトのwriteメソッドを呼び出して、OutputStreamに出力します(8)。ここではファイルに書き込むのでFileOutputStreamオブジェクトを引数として渡しています。
4.1.動的Excelファイルのダウンロードそれでは次に、Webアプリケーションらしく、動的に生成したExcelファイルをブラウザからダウンロードできるようにしてみましょう。Excelファイルのようなバイナリデータの生成をJSPで行うことはできないため、サーブレットを使います(リスト10)。
リスト10 ExcelGenerateServlet.java
package poisample;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.poi.hssf.usermodel.*;
public class ExcelGenerateServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
wb.setSheetName(0,
"ダウンロード",HSSFWorkbook.ENCODING_UTF_16);
//文字列の書き込み
HSSFCell cell = sheet.createRow(0).createCell((short)1);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue("ダウンロードサンプル");
//送信
response.setHeader("Content-Disposition",
"attachment;filename=download.xls");
response.setContentType("application/vnd.ms-excel");
wb.write(response.getOutputStream());
}
}
このサーブレットは、web.xmlに記述したマッピングによってhttp://localhost:8080/poi/ExcelGenereteにアクセスすることで実行されるようになっています。アクセスすると、ダウンロードが始まります(図12)。
図12 「ファイルのダウンロード」ダイアログ
保存すると、図13のようなExcelファイルが生成されています。
図13 生成されたExcelファイル
ダウンロード時のContentTypeは「application/vnd.ms-excel」としています(1)。また、初期ファイル名を指定するためにContent-Dispositionヘッダでファイル名を指定しています(2)。
サーブレットからの送信は、HSSFWorkbookオブジェクトのwriteメソッドにHttpServletResponse#getOutputStreamメソッドの戻り値を渡すことで行われています(3)。
4.2.書式の設定単純な出力ができるようになったので、次はさまざまな書式を設定してみます(リスト11)。
リスト11 StyleServlet.java
package poisample;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
public class StyleServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
wb.setSheetName(0,"書式",HSSFWorkbook.ENCODING_UTF_16);
//セル幅
sheet.setColumnWidth((short)0,(short)5120);//140ピクセル
sheet.setColumnWidth((short)1,(short)7680);//210ピクセル
sheet.setColumnWidth((short)2,(short)7680);//210ピクセル
HSSFRow row;
HSSFCell cell;
HSSFCellStyle style;
HSSFFont font;
//背景・罫線
row = sheet.createRow((short)1);
cell = row.createCell((short)0);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue("背景色");
style = wb.createCellStyle();
style.setFillForegroundColor(HSSFColor.BRIGHT_GREEN.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
style.setBorderTop(HSSFCellStyle.BORDER_DOUBLE);
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
cell.setCellStyle(style);
//日付
cell = row.createCell((short)1);
cell.setCellValue(new java.util.Date());
style = wb.createCellStyle();
style.setDataFormat((short)22);
cell.setCellStyle(style);
//フォント
row = sheet.createRow((short)2);
String[] fonts = {
"MS Pゴシック","MS P明朝","HG創英角ポップ体"};
for(short col = 0; col < 3; ++col){
cell = row.createCell(col);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue(fonts[col]);
font = wb.createFont();
font.setFontName(fonts[col]);
font.setFontHeight((short)320);//16ポイント
style = wb.createCellStyle();
style.setFont(font);
cell.setCellStyle(style);
}
//送信
response.setHeader("Content-Disposition",
"attachment;filename=style.xls");
response.setContentType("application/vnd.ms-excel");
wb.write(response.getOutputStream());
}
}
このサーブレットは/StyleというURLにマッピングするようにweb.xmlに記述しています。http://localhost:8080/poi/Styleにアクセスすることでサーブレットによって生成されたExcelファイルのダウンロードが始まります。保存すると図14のようなファイルになります。
図14 生成されたExcelファイル
このサンプルでは、セル幅・背景色・罫線・日付・フォントサイズ・フォントの種類を設定しています。
セル幅は、HSSFSheetオブジェクトのsetColumnWidthメソッドで指定します(1)。このとき指定する数値は2560が70ピクセルにあたります。
セルの書式はHSSFCellStyleクラスが管理します。
日付を設定する際に、setDataFormatメソッドで日付のフォーマットを指定する必要があります(2)。日付のフォーマットとして引数に渡すことができる値には表7のようなものがあります。
フォントはHSSFFontクラスで管理しています(表8)。フォントサイズはsetFontHeightメソッドで指定しますが(4)、このとき指定する数値は20が1ポイントにあたります。
フォントの種類はsetFontNameメソッドで指定します(3)。図14を見ると、MSゴシックとMS明朝はうまく設定できているのですが、HG創英角ポップ体はうまく設定できていません。MSゴシックとMS明朝以外の日本語名のフォントはうまく設定できないようです。
日付フォーマット
14 2002/11/2
31 2002年11月2日
55 2002年11月
56 11月2日
57 H14.11.2
58 平成14年11月2日
177 11/2
22 2002/11/2 0:00
176 2002/11/2 12:00 AM
org.apache.poi.hssf.usermodel.HSSFFont
フォント
short BOLDWEIGHT_BOLD ボールド体を示す値
void setBoldweight(short value) 太さの設定・取得
short getBoldweight()
void setFontHeight(short value) フォントサイズの設定・取得
short getFontHeight()
void setFontName(String value) フォント名の設定・取得
String getFontName()
void setStrikeout(boolean value) 打ち消し線の設定・取得
boolean getStrikeout()
void setUnderline(boolean value) 下線の設定・取得
boolean getUnderline()
HSSFFontの主なメンバ
4.3.書式テンプレートプログラムでいちいち書式を設定するのも面倒なので、書式を指定したファイル(図15)をあらかじめ用意するようにしてみましょう(リスト12)。
リスト12 RyoshuServlet.java
package poisample;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.*;
public class RyoshuServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String path = getServletContext().getRealPath(
"/xls/ryoshu-template.xls");
InputStream is = new FileInputStream(path);
POIFSFileSystem fs = new POIFSFileSystem(is);
is.close();
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFCell cell;
//宛名
cell = sheet.getRow((short)3).getCell((short)1);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellValue("評論工務店様");
//日付
cell = sheet.getRow((short)2).getCell((short)5);
cell.setCellValue(new java.util.Date());
//金額
cell = sheet.getRow((short)7).getCell((short)1);;
cell.setCellValue(15000);
//送信
response.setHeader("Content-Disposition",
"attachment;filename=ryoshu.xls");
response.setContentType("application/vnd.ms-excel");
wb.write(response.getOutputStream());
}
}
図15 リスト表示用のテンプレート
図15のファイルは、あらかじめSAMPLE_HOME\xls\ryoshu-template.xlsとして用意しておきます。この中の宛名・日付・金額の部分をサーブレットで変更して送信するようにします。
このサーブレットは/RyoshuというURLにマッピングするようにweb.xmlに記述しています。http://localhost:8080/poi/Ryoshuにアクセスすることでサーブレットによって生成されたExcelファイルのダウンロードが始まります。保存すると図16のようなファイルになります。
図16 作成されたファイル
このようにすると、Excelを書式エディタとして使うことができます。PDFの場合は柔軟なレイアウトができますが、PDF作成ツールは普及率が低く、また、操作も煩雑になりがちです。その点、Excelはレイアウトの制限は大きいのですが、普及率も高くレイアウト作成の操作も簡単です。
また、テンプレートファイルで用意しておけば、日本語名のフォントなどPOIでは扱えないものも問題なく扱えるようです。簡単な印刷フォームとして利用すると便利なのではないでしょうか。
4.4.書式付リストの出力最後に、書式テンプレートを元にリストを出力するサンプルをご紹介します(リスト13)。あらかじめ、図17のようなファイルを用意しておきます。
リスト13 ListServlet.java
package poisample;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.*;
public class ListServlet extends HttpServlet {
String[][] sampledata = {
{"なかやま","モツ鍋","大橋","4000"},
{"ショッパイヤ","ブラジル料理","西通り","3000"},
{"九ちゃん","ラーメン","大宰府","500"}};
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String path = getServletContext().getRealPath("/list-template2.xls");
InputStream is = new FileInputStream(path);
POIFSFileSystem fs = new POIFSFileSystem(is);
is.close();
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
//スタイル取得
HSSFCellStyle[] styles = new HSSFCellStyle[sampledata[0].length];
HSSFRow row = sheet.getRow((short)3);
for(short i = 0; i < styles.length; ++i){
styles[i] = row.getCell(i).getCellStyle();
}
for(int i = 0; i < sampledata.length; ++i){
//行作成
if(i > 0){
//2行目以降
sheet.shiftRows(i + 3,i + 3 ,1);
row = sheet.createRow(i + 3);
for(short j = 0; j < sampledata[i].length; ++j) row.createCell(j);
}
else{
//最初のデータ
row = sheet.getRow(i + 3);
}
for(short j = 0; j < sampledata[i].length; ++j){
HSSFCell cell = row.getCell(j);
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
cell.setCellStyle(styles[j]);
if(j < 3){
cell.setCellValue(sampledata[i][j]);
}else{
cell.setCellValue(Integer.parseInt(sampledata[i][j]));
}
}
}
//平均の計算式
row = sheet.getRow(sampledata.length + 3);
if(row != null){
HSSFCell cell = row.getCell((short)3);
if(cell != null){
String f = "average(d4:d" + (3 + sampledata.length) + ")";
cell.setCellFormula(f);
}
}
//送信
response.setHeader("Content-Disposition", "attachment;filename=list.xls");
response.setContentType("application/vnd.ms-excel");
wb.write(response.getOutputStream());
}
}
図17 テンプレート用のExcelファイル
図17のファイルを、SAMPLE_HOME\xls\listtemplate.xlsとして用意します。
このサーブレットは/ListというURLにマッピングするようにweb.xmlに記述しています。http://localhost:8080/poi/Listにアクセスすることでサーブレットによって生成されたExcelファイルのダウンロードが始まります。保存すると図18のようなファイルになります。
図18 生成されたExcelファイル
書式テンプレートの4行めの書式を元に、各行が書式設定されています。
行を挿入するメソッドは無いようなので、HSSFSheet#shiftRowsメソッドで下部の行をシフトさせています(1)。このとき、こうやって行をシフトさせても「=sum(d3:d4)」など計算式で示されているセルは変わらないので注意が必要です。
5.まとめ
以上のように、Excelファイルを扱うことができれば、アプリケーションの幅も広がります。また、今回は試していませんが、POI 2.0からはグラフを扱うこともできるようになるようです。グラフの扱いがうまくできるようになれば、また、POIを使った応用がさらにいろいろ考えられそうです。
--------------------------------------------------------------------------------
Copyright (c) 2001-2004 Naoki Kishida All Rights Reserved.
http://www.fk.urban.ne.jp/home/kishida/
2010年9月22日水曜日
2010年9月17日金曜日
「Connection is closed. Operation is not permitted.」の対処方法
以下のようなconnection.createStatement();の記述場所が不適切な場合に、
statement = connection.createStatement(); //←ココ
while(rs_dseq.next()){
String strDrop = "DROP SEQUENCE " + rs_dseq.getString("relname");
statement.execute(strDrop);
}
「Connection is closed. Operation is not permitted.」エラーが発生することがあります。
(コネクション イズ クローズド オペレーション イズ ノット パーミッティッド)
その場合はwhileループの中でconnection.createStatement();を実施する必要があります。
while(rs_dseq.next()){
statement = connection.createStatement(); //←ココ
String strDrop = "DROP SEQUENCE " + rs_dseq.getString("relname");
statement.execute(strDrop);
}
statement = connection.createStatement(); //←ココ
while(rs_dseq.next()){
String strDrop = "DROP SEQUENCE " + rs_dseq.getString("relname");
statement.execute(strDrop);
}
「Connection is closed. Operation is not permitted.」エラーが発生することがあります。
(コネクション イズ クローズド オペレーション イズ ノット パーミッティッド)
その場合はwhileループの中でconnection.createStatement();を実施する必要があります。
while(rs_dseq.next()){
statement = connection.createStatement(); //←ココ
String strDrop = "DROP SEQUENCE " + rs_dseq.getString("relname");
statement.execute(strDrop);
}
2010年9月14日火曜日
データベーススペシャリスト試験解説
SQLインジェクション対策として行う特殊文字の無効化操作はどれか。
ア
クロスサイトスクリプティング
イ
サニタイジング
ウ
パケットフィルタリング
エ
フィッシング
SQLインジェクションとはSQLに悪意を持ったパラメータを渡すことによって、
データベース側に攻撃を仕掛ける方法です。
そうしたことからユーザからのパラメータを洗浄すると言う意味で「サニタイジング」という対策がとられます。
よって正解は「イ」
ア
クロスサイトスクリプティング
イ
サニタイジング
ウ
パケットフィルタリング
エ
フィッシング
SQLインジェクションとはSQLに悪意を持ったパラメータを渡すことによって、
データベース側に攻撃を仕掛ける方法です。
そうしたことからユーザからのパラメータを洗浄すると言う意味で「サニタイジング」という対策がとられます。
よって正解は「イ」
2010年9月13日月曜日
データベーススペシャリスト過去問解説
データベーススペシャリスト過去問解説
通信回線を使用したデータ送信システムに
M/M/1の待ち行列モデルを適用したとする。
平均回線待ち時間と平均伝送時間、回線利用率の関係は以下のようになります。
平均回線待ち時間=平均伝送時間×(回線利用率÷(1-回線利用率))
通信回線を使用したデータ送信システムに
M/M/1の待ち行列モデルを適用したとする。
平均回線待ち時間と平均伝送時間、回線利用率の関係は以下のようになります。
平均回線待ち時間=平均伝送時間×(回線利用率÷(1-回線利用率))
Javaで安全な通番を作成するには【シーケンスSequence編】
//*************************************************************************
//Javaで通番を作成
//import java.sql.*;
//import java.text.SimpleDateFormat;
//import java.util.Calendar;
//*************************************************************************
public int getTuban(){
Calendar t_day = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
String seaquence_name = "seq" + format.format(t_day.getTime());
int result1 = 0;
try{
//シーケンス存在確認(無ければ作成)
ResultSet rs_seq = statement.executeQuery("SELECT COUNT(*) AS cnt FROM pg_statio_user_sequences WHERE relname='" + seaquence_name + "'");
rs_seq.next();
int reccount = rs_seq.getInt("cnt");
rs_seq.close();
if(reccount==0){
//過去日のシーケンスを削除
ResultSet rs_dseq = statement.executeQuery("SELECT relname FROM pg_statio_user_sequences WHERE relname like 'seq2%'");
while(rs_dseq.next()){
statement.execute("DROP SEAQUENCE " + rs_dseq.getString("relname"));
}
//新しくシーケンスを作成
StringBuilder sb1 = new StringBuilder("");
sb1.append("CREATE SEQUENCE ").append(seaquence_name);
sb1.append(" INCREMENT 1");
sb1.append(" MINVALUE 1");
sb1.append(" MAXVALUE 9999");
sb1.append(" START 1");
sb1.append(" CACHE 1");
sb1.append(" CYCLE;");
sb1.append("ALTER TABLE ").append(seaquence_name).append(" OWNER TO postgres;");
statement.execute(sb1.toString());
}
//連番呼び出し
ResultSet rs_nextval = statement.executeQuery("SELECT nextval('" + seaquence_name + "') AS tuban");
rs_nextval.next();
result1 = rs_nextval.getInt("tuban");
rs_nextval.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
return result1;
}
//Javaで通番を作成
//import java.sql.*;
//import java.text.SimpleDateFormat;
//import java.util.Calendar;
//*************************************************************************
public int getTuban(){
Calendar t_day = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
String seaquence_name = "seq" + format.format(t_day.getTime());
int result1 = 0;
try{
//シーケンス存在確認(無ければ作成)
ResultSet rs_seq = statement.executeQuery("SELECT COUNT(*) AS cnt FROM pg_statio_user_sequences WHERE relname='" + seaquence_name + "'");
rs_seq.next();
int reccount = rs_seq.getInt("cnt");
rs_seq.close();
if(reccount==0){
//過去日のシーケンスを削除
ResultSet rs_dseq = statement.executeQuery("SELECT relname FROM pg_statio_user_sequences WHERE relname like 'seq2%'");
while(rs_dseq.next()){
statement.execute("DROP SEAQUENCE " + rs_dseq.getString("relname"));
}
//新しくシーケンスを作成
StringBuilder sb1 = new StringBuilder("");
sb1.append("CREATE SEQUENCE ").append(seaquence_name);
sb1.append(" INCREMENT 1");
sb1.append(" MINVALUE 1");
sb1.append(" MAXVALUE 9999");
sb1.append(" START 1");
sb1.append(" CACHE 1");
sb1.append(" CYCLE;");
sb1.append("ALTER TABLE ").append(seaquence_name).append(" OWNER TO postgres;");
statement.execute(sb1.toString());
}
//連番呼び出し
ResultSet rs_nextval = statement.executeQuery("SELECT nextval('" + seaquence_name + "') AS tuban");
rs_nextval.next();
result1 = rs_nextval.getInt("tuban");
rs_nextval.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
return result1;
}
2010年9月2日木曜日
Javaで切り上げMath.ceil()
Javaで切り上げMath.ceil()
【切り上げ】
double d1 = (double)5/2;
System.out.println(Math.ceil(d1));
結果 3.0
【よくあるミス】
//intで割っているので小数がなくなる2.5ではなく2(2.0)
double d1 = 5/2;
System.out.println(Math.ceil(d1));
結果 2.0
【切り上げ】
double d1 = (double)5/2;
System.out.println(Math.ceil(d1));
結果 3.0
【よくあるミス】
//intで割っているので小数がなくなる2.5ではなく2(2.0)
double d1 = 5/2;
System.out.println(Math.ceil(d1));
結果 2.0
2010年8月31日火曜日
JFreeChartにapplication.getRealPath("")を渡す方法
page5.jspでグラフクラスを呼び出す
//==========================================================================================
//¥(円マーク)を¥¥(円円)に置き換える
BarChart2 chart = new BarChart2(application.getRealPath("").replace("\\", "\\\\"));
chart.setAppPath(application.getRealPath("").replace("\\", "\\\\"));
chart.setGraphData(gb1.graphData);
chart.DrawGraph();
//==========================================================================================
//==========================================================================================
//グラフ作成クラス本体
//==========================================================================================
package chart;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.channels.FileChannel;
import javax.imageio.ImageIO;
import org.jfree.chart.*;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.servlet.ServletUtilities;
//import org.jfree.chart.title.*;
import org.jfree.data.category.DefaultCategoryDataset;
/**
* 棒グラフのサンプル
*/
public class BarChart2 {
String x;
String appPath;
//データ作成
public String[][] graphData;
public static void main(String[] args) {
//new BarChart2();
}
public BarChart2(String aPath){
appPath = aPath;
}
public void DrawGraph(){
// 表示するデータの作成
String series1 = "第一";
String series2 = "第二";
String series3 = "第三";
// カテゴリーの設定
String category1 = "カテゴリー 1";
String category2 = "カテゴリー 2";
String category3 = "カテゴリー 3";
//レガシーテーマを設定する
ChartFactory.setChartTheme(StandardChartTheme.createLegacyTheme());
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
for(int i=0;i<31;i++){
if((!graphData[0][i].equals("")) && (!graphData[1][i].equals(""))){
dataset.addValue(Integer.parseInt(graphData[0][i]), graphData[1][i], category1);
}
}
// JFreeChartオブジェクトの生成(タイトル、項目名など)
JFreeChart chart = ChartFactory.createBarChart("日付別売上状況",
null, ".", dataset, PlotOrientation.VERTICAL, true, true, false);
try {
x = ServletUtilities.saveChartAsJPEG(chart, 500, 500,null);
String sFile = System.getProperty("java.io.tmpdir") + "\\" + x;
String dFile = this.appPath + "\\" + x;
copyTransfer(sFile,dFile);
} catch (Exception e) {
//e.printStackTrace();
}
}
public void setGraphData(String[][] values){
graphData = new String[100][100];
graphData = values;
}
public String getName(){
return x;
}
public void setAppPath(String value_path){
this.appPath = value_path;
}
/**
* コピー元のパス[srcPath]から、コピー先のパス[destPath]へ
* ファイルのコピーを行います。
* コピー処理にはFileChannel#transferToメソッドを利用します。
* 尚、コピー処理終了後、入力・出力のチャネルをクローズします。
* @param srcPath コピー元のパス
* @param destPath コピー先のパス
* @throws IOException 何らかの入出力処理例外が発生した場合
*/
public static void copyTransfer(String srcPath, String destPath)
throws IOException {
FileChannel srcChannel = new
FileInputStream(srcPath).getChannel();
FileChannel destChannel = new
FileOutputStream(destPath).getChannel();
try {
srcChannel.transferTo(0, srcChannel.size(), destChannel);
} finally {
srcChannel.close();
destChannel.close();
}
}
public BarChart2(){
// 表示するデータの作成
String series1 = "第一";
String series2 = "第二";
String series3 = "第三";
// カテゴリーの設定
String category1 = "カテゴリー 1";
String category2 = "カテゴリー 2";
String category3 = "カテゴリー 3";
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(1.0, series1, category1);
dataset.addValue(4.0, series1, category2);
dataset.addValue(5.0, series1, category3);
dataset.addValue(5.0, series2, category1);
dataset.addValue(7.0, series2, category2);
dataset.addValue(7.0, series2, category3);
dataset.addValue(6.0, series3, category1);
dataset.addValue(8.0, series3, category2);
dataset.addValue(8.0, series3, category3);
// JFreeChartオブジェクトの生成(タイトル、項目名など)
JFreeChart chart = ChartFactory.createBarChart("棒グラフのサンプル",
null, "値", dataset, PlotOrientation.VERTICAL, true, true, false);
FileOutputStream jpg = null;
try {
//x = ".\\test.jpg";
//jpg = new FileOutputStream(x);
x = ServletUtilities.saveChartAsJPEG(chart, 500, 500,null);
String sFile = System.getProperty("java.io.tmpdir") + "\\" + x;
String dFile = this.appPath + "\\" + x;
copyTransfer(sFile,dFile);
//dFile = "C:\\MyWork\\pgUriage011\\Upp011\\build\\web" + "\\" + x;
//copyTransfer(sFile,dFile);
//dFile = "C:\\MyWork\\pgUriage011\\Upp011\\web" + "\\" + x;
//copyTransfer(sFile,dFile);
//ChartUtilities.writeChartAsJPEG(jpg,chart, 500, 500,null);
} catch (Exception e) {
//e.printStackTrace();
}
// グラフの出力(png,jpgで出力できます)
//File outputFile = new File("e:/temp/SampleBarChart.png");
//try {
// ChartUtilities.saveChartAsPNG(outputFile, chart, 500, 500);
//} catch (IOException ioEx) {
// //ioEx.printStackTrace();
//}
// バイナリ出力ストリームにJPEG形式で画像を出力
}
}
//==========================================================================================
//¥(円マーク)を¥¥(円円)に置き換える
BarChart2 chart = new BarChart2(application.getRealPath("").replace("\\", "\\\\"));
chart.setAppPath(application.getRealPath("").replace("\\", "\\\\"));
chart.setGraphData(gb1.graphData);
chart.DrawGraph();
//==========================================================================================
//==========================================================================================
//グラフ作成クラス本体
//==========================================================================================
package chart;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.channels.FileChannel;
import javax.imageio.ImageIO;
import org.jfree.chart.*;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.servlet.ServletUtilities;
//import org.jfree.chart.title.*;
import org.jfree.data.category.DefaultCategoryDataset;
/**
* 棒グラフのサンプル
*/
public class BarChart2 {
String x;
String appPath;
//データ作成
public String[][] graphData;
public static void main(String[] args) {
//new BarChart2();
}
public BarChart2(String aPath){
appPath = aPath;
}
public void DrawGraph(){
// 表示するデータの作成
String series1 = "第一";
String series2 = "第二";
String series3 = "第三";
// カテゴリーの設定
String category1 = "カテゴリー 1";
String category2 = "カテゴリー 2";
String category3 = "カテゴリー 3";
//レガシーテーマを設定する
ChartFactory.setChartTheme(StandardChartTheme.createLegacyTheme());
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
for(int i=0;i<31;i++){
if((!graphData[0][i].equals("")) && (!graphData[1][i].equals(""))){
dataset.addValue(Integer.parseInt(graphData[0][i]), graphData[1][i], category1);
}
}
// JFreeChartオブジェクトの生成(タイトル、項目名など)
JFreeChart chart = ChartFactory.createBarChart("日付別売上状況",
null, ".", dataset, PlotOrientation.VERTICAL, true, true, false);
try {
x = ServletUtilities.saveChartAsJPEG(chart, 500, 500,null);
String sFile = System.getProperty("java.io.tmpdir") + "\\" + x;
String dFile = this.appPath + "\\" + x;
copyTransfer(sFile,dFile);
} catch (Exception e) {
//e.printStackTrace();
}
}
public void setGraphData(String[][] values){
graphData = new String[100][100];
graphData = values;
}
public String getName(){
return x;
}
public void setAppPath(String value_path){
this.appPath = value_path;
}
/**
* コピー元のパス[srcPath]から、コピー先のパス[destPath]へ
* ファイルのコピーを行います。
* コピー処理にはFileChannel#transferToメソッドを利用します。
* 尚、コピー処理終了後、入力・出力のチャネルをクローズします。
* @param srcPath コピー元のパス
* @param destPath コピー先のパス
* @throws IOException 何らかの入出力処理例外が発生した場合
*/
public static void copyTransfer(String srcPath, String destPath)
throws IOException {
FileChannel srcChannel = new
FileInputStream(srcPath).getChannel();
FileChannel destChannel = new
FileOutputStream(destPath).getChannel();
try {
srcChannel.transferTo(0, srcChannel.size(), destChannel);
} finally {
srcChannel.close();
destChannel.close();
}
}
public BarChart2(){
// 表示するデータの作成
String series1 = "第一";
String series2 = "第二";
String series3 = "第三";
// カテゴリーの設定
String category1 = "カテゴリー 1";
String category2 = "カテゴリー 2";
String category3 = "カテゴリー 3";
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(1.0, series1, category1);
dataset.addValue(4.0, series1, category2);
dataset.addValue(5.0, series1, category3);
dataset.addValue(5.0, series2, category1);
dataset.addValue(7.0, series2, category2);
dataset.addValue(7.0, series2, category3);
dataset.addValue(6.0, series3, category1);
dataset.addValue(8.0, series3, category2);
dataset.addValue(8.0, series3, category3);
// JFreeChartオブジェクトの生成(タイトル、項目名など)
JFreeChart chart = ChartFactory.createBarChart("棒グラフのサンプル",
null, "値", dataset, PlotOrientation.VERTICAL, true, true, false);
FileOutputStream jpg = null;
try {
//x = ".\\test.jpg";
//jpg = new FileOutputStream(x);
x = ServletUtilities.saveChartAsJPEG(chart, 500, 500,null);
String sFile = System.getProperty("java.io.tmpdir") + "\\" + x;
String dFile = this.appPath + "\\" + x;
copyTransfer(sFile,dFile);
//dFile = "C:\\MyWork\\pgUriage011\\Upp011\\build\\web" + "\\" + x;
//copyTransfer(sFile,dFile);
//dFile = "C:\\MyWork\\pgUriage011\\Upp011\\web" + "\\" + x;
//copyTransfer(sFile,dFile);
//ChartUtilities.writeChartAsJPEG(jpg,chart, 500, 500,null);
} catch (Exception e) {
//e.printStackTrace();
}
// グラフの出力(png,jpgで出力できます)
//File outputFile = new File("e:/temp/SampleBarChart.png");
//try {
// ChartUtilities.saveChartAsPNG(outputFile, chart, 500, 500);
//} catch (IOException ioEx) {
// //ioEx.printStackTrace();
//}
// バイナリ出力ストリームにJPEG形式で画像を出力
}
}
2010年8月30日月曜日
JFreeChart一般概論 ファイル保存
JFreeChartと格闘中ですが以下の3つの操作で表示させます。
JSP側の処理
⇒application.getRealPath()によりWEB-INFのパスをドライブからのパスに変換する
(例 mychart.setRealPath(application.getRealPath);) //build/web
JavaBeans側の処理
⇒tempにコピーされた*****.jpgを以下のコピー関数でJSPカレントフォルダへコピー
(例 copyTransfer(tempFolder, realPath);)
JSP側でカレントフォルダの画像を見に行く
/**
* コピー元のパス[srcPath]から、コピー先のパス[destPath]へ
* ファイルのコピーを行います。
* コピー処理にはFileChannel#transferToメソッドを利用します。
* 尚、コピー処理終了後、入力・出力のチャネルをクローズします。
* @param srcPath コピー元のパス
* @param destPath コピー先のパス
* @throws IOException 何らかの入出力処理例外が発生した場合
*/
public static void copyTransfer(String srcPath, String destPath)
throws IOException {
FileChannel srcChannel = new
FileInputStream(srcPath).getChannel();
FileChannel destChannel = new
FileOutputStream(destPath).getChannel();
try {
srcChannel.transferTo(0, srcChannel.size(), destChannel);
} finally {
srcChannel.close();
destChannel.close();
}
}
JSP側の処理
⇒application.getRealPath()によりWEB-INFのパスをドライブからのパスに変換する
(例 mychart.setRealPath(application.getRealPath);) //build/web
JavaBeans側の処理
⇒tempにコピーされた*****.jpgを以下のコピー関数でJSPカレントフォルダへコピー
(例 copyTransfer(tempFolder, realPath);)
JSP側でカレントフォルダの画像を見に行く
/**
* コピー元のパス[srcPath]から、コピー先のパス[destPath]へ
* ファイルのコピーを行います。
* コピー処理にはFileChannel#transferToメソッドを利用します。
* 尚、コピー処理終了後、入力・出力のチャネルをクローズします。
* @param srcPath コピー元のパス
* @param destPath コピー先のパス
* @throws IOException 何らかの入出力処理例外が発生した場合
*/
public static void copyTransfer(String srcPath, String destPath)
throws IOException {
FileChannel srcChannel = new
FileInputStream(srcPath).getChannel();
FileChannel destChannel = new
FileOutputStream(destPath).getChannel();
try {
srcChannel.transferTo(0, srcChannel.size(), destChannel);
} finally {
srcChannel.close();
destChannel.close();
}
}
JSP/Servletでグラフを描画『jfreechart』
JSP/Servletでグラフを描画『jfreechart』
WEB上にあるサンプルどおりに作成したら、
グラフは作成できたもののTmcat5\tempフォルダに出力されてしまうため
JSPから表示できませんでした。
そこで暫定的に以下の方法で逃げることに
1、ファイルをjsp/imgフォルダにコピー
2、JSPからimgにコピーしたファイルを表示させる
とりあえず動きますがコピー処理が無駄ですね
直接出力フォルダの設定はできないものか・・・・
グラフ画像コピー関数(参考)
/**
* コピー元のパス[srcPath]から、コピー先のパス[destPath]へ
* ファイルのコピーを行います。
* コピー処理にはFileChannel#transferToメソッドを利用します。
* 尚、コピー処理終了後、入力・出力のチャネルをクローズします。
* @param srcPath コピー元のパス
* @param destPath コピー先のパス
* @throws IOException 何らかの入出力処理例外が発生した場合
*/
public static void copyTransfer(String srcPath, String destPath)
throws IOException {
FileChannel srcChannel = new
FileInputStream(srcPath).getChannel();
FileChannel destChannel = new
FileOutputStream(destPath).getChannel();
try {
srcChannel.transferTo(0, srcChannel.size(), destChannel);
} finally {
srcChannel.close();
destChannel.close();
}
}
WEB上にあるサンプルどおりに作成したら、
グラフは作成できたもののTmcat5\tempフォルダに出力されてしまうため
JSPから表示できませんでした。
そこで暫定的に以下の方法で逃げることに
1、ファイルをjsp/imgフォルダにコピー
2、JSPからimgにコピーしたファイルを表示させる
とりあえず動きますがコピー処理が無駄ですね
直接出力フォルダの設定はできないものか・・・・
グラフ画像コピー関数(参考)
/**
* コピー元のパス[srcPath]から、コピー先のパス[destPath]へ
* ファイルのコピーを行います。
* コピー処理にはFileChannel#transferToメソッドを利用します。
* 尚、コピー処理終了後、入力・出力のチャネルをクローズします。
* @param srcPath コピー元のパス
* @param destPath コピー先のパス
* @throws IOException 何らかの入出力処理例外が発生した場合
*/
public static void copyTransfer(String srcPath, String destPath)
throws IOException {
FileChannel srcChannel = new
FileInputStream(srcPath).getChannel();
FileChannel destChannel = new
FileOutputStream(destPath).getChannel();
try {
srcChannel.transferTo(0, srcChannel.size(), destChannel);
} finally {
srcChannel.close();
destChannel.close();
}
}
2010年8月27日金曜日
属性valueはどんな式も受け付けません
タグライブラリの<c:out value="${data}"></c:out>などのように
valueに式を入れたい時に、
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
を使用すると「」
属性valueはどんな式も受け付けません
according to tld or attribute directive in tag file, attribute value does not accept any expressions
【原因】
タグライブラリが古い
【解決方法】
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
まず上のタグに変更します。(uriが多少異なります)
すると
the absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
な感じのエラーが発生するので
最新のタグライブラリの
jstl.jar
standard.jar
をプロジェクトのライブラリに追加しておきます。
valueに式を入れたい時に、
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
を使用すると「」
属性valueはどんな式も受け付けません
according to tld or attribute directive in tag file, attribute value does not accept any expressions
【原因】
タグライブラリが古い
【解決方法】
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
まず上のタグに変更します。(uriが多少異なります)
すると
the absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
な感じのエラーが発生するので
最新のタグライブラリの
jstl.jar
standard.jar
をプロジェクトのライブラリに追加しておきます。
javax.servlet.ServletException: org.postgresql.Driver 解決方法
javax.servlet.ServletException: org.postgresql.Driver
というエラーが発生したらpostgreSQLのDriverにパスが通っていないのが原因です。
pg73jdbc3.jarをライブラリに追加すればOKです。
というエラーが発生したらpostgreSQLのDriverにパスが通っていないのが原因です。
pg73jdbc3.jarをライブラリに追加すればOKです。
JSP/ServletでCONTEXT-PARAM(コンテキスト-パラメータ)を使用
JSP/ServletでCONTEXT-PARAM(コンテキスト-パラメータ)を使用する方法です。
web.xmlの<web-app>内に以下を記述
<!-- -->
<context-param>
<param-name>dbdriver</param-name>
<param-value>org.postgresql.Driver</param-value>
</context-param> <context-param>
<param-name>dburl</param-name>
<param-value>jdbc:postgresql://localhost:5432/dbsv</param-value>
</context-param> <context-param>
<param-name>dbuser</param-name>
<param-value>postgres</param-value>
</context-param> <context-param>
<param-name>dbpassword</param-name>
<param-value>zxcvvcxz</param-value>
</context-param>
<!-- -->
値の取得はJSPファイルまたはサーブレット内で
application.getInitParameter("dbdriver");
application.getInitParameter("dburl");
application.getInitParameter("dbuser");
application.getInitParameter("dbpassword");
web.xmlの<web-app>内に以下を記述
<!-- -->
<context-param>
<param-name>dbdriver</param-name>
<param-value>org.postgresql.Driver</param-value>
</context-param> <context-param>
<param-name>dburl</param-name>
<param-value>jdbc:postgresql://localhost:5432/dbsv</param-value>
</context-param> <context-param>
<param-name>dbuser</param-name>
<param-value>postgres</param-value>
</context-param> <context-param>
<param-name>dbpassword</param-name>
<param-value>zxcvvcxz</param-value>
</context-param>
<!-- -->
値の取得はJSPファイルまたはサーブレット内で
application.getInitParameter("dbdriver");
application.getInitParameter("dburl");
application.getInitParameter("dbuser");
application.getInitParameter("dbpassword");
2010年8月26日木曜日
自宅サーバ公開方法(Tomcat:8080)
自宅サーバ公開方法
今回の接続方法
■パソコン=ルータ(モデム)=外部■
上記の接続でいきたいと思います。
つまり自宅のパソコンをWEBサーバにして、
ルータのポートを開放するという方法で行きます。
【手順】
1、パソコンにWEBサーバソフトをインストール
今回はTomcatにします。(本来はApacheサーバが良い)
8080ポートを開放します。(詳しい方は80ポートを開放してください)
2、ルータの8080(80)ポートを開放します。
以上で設定は完了です。簡単ですね。
実際に動かすのはHTMLソースにします。
後日JSP/Servletへ移行します。
今回の接続方法
■パソコン=ルータ(モデム)=外部■
上記の接続でいきたいと思います。
つまり自宅のパソコンをWEBサーバにして、
ルータのポートを開放するという方法で行きます。
【手順】
1、パソコンにWEBサーバソフトをインストール
今回はTomcatにします。(本来はApacheサーバが良い)
8080ポートを開放します。(詳しい方は80ポートを開放してください)
2、ルータの8080(80)ポートを開放します。
以上で設定は完了です。簡単ですね。
実際に動かすのはHTMLソースにします。
後日JSP/Servletへ移行します。
2010年8月25日水曜日
keiba
私の必勝法の基本的考え方
1)競馬もギャンブルなので、絶対という事ははあり得ません。
つまり、私の必勝法でも100%はありません。
2)具体的には、96年上半期(1月ー6月)中央競馬は、各地で144日
開催されましたが、全ての日に馬券を購入したとして、
負けるのは5日だけです、残りの139日は全て勝ちます。
つまり、私の必勝法の勝率は96.5%です。
「私は、自分の必勝法を94年位にほぼ完成させました、95年より
実際に試してみて、これはいけると確信いたしました。」
3)私の必勝法は、1万円が当日に20万円や30万円になるものでは
ありませんしかし、馬券購入当日は確実に勝ちます(96.5%)。
現実的には、1ヶ月(8日間)で8万円から20万円位のプラス
と考えて下さい。
4)競馬をやっている人は感じないと思いますが、
ゴールの瞬間の鼻差や首差のVIDEOを見て、
こんなのが当てられるハズがないと、
普通の人は感じます。
事実、皆様の廻りで1ヶ月(8日間)全日馬券を購入して、全日プラス
の人はいないと思います。
つまり、これは、基本的考え方に間違いがあると思われます。
5)パチンコのプロはいますが、競馬のプロはいません。
これは、騎手・血統・馬場状況・距離などを基にした従来の方法に、
大きな問題があると思われます。
6)皆様の中には、パチンコをしている人もいらっしゃるでしょう。
パチンコをしている人は、
パチンコの必勝法をほとんどの人が知っています。
つまり、 パチンコで勝つためには、
朝1からパチンコをしなくてはなりません。
夕方、会社が終わって6時頃から2-4時間打って毎日勝つ事は
不可能です。
たまには勝つかも知れませんが、ほとんど負けます。
この事を知っているのに、何故皆様は気づかないのでしょう、
そうです!
競馬も勝つためには、朝1からしなくてはなりません、
メインレースだけしていても勝てないのです。
7)スポーツ新聞等では、大穴や万馬券をどれだけ当てたかを
大々的に宣伝していますが、万馬券を当てようとして馬券を購入することは、
勝つ確率がかなり低いということです。
確率が低いのは低いのではなく、負ける事だと気づいて下さい。
負けるという事は、お金が無くなる事なのです。
馬券は、宝くじ感覚で買うものではありません。
◆競馬が飯より好きな方に一言◆
再三さいし注意してますが、皆さんは、予想や攻略法を買っても絶対に
自分の考えや買い目を入れてしまいます、こうすると、その予想や必勝法が
どの程度有効性のあるモノかが、分からなくなってしまいます、お金を出して
商品を買ってるのを忘れてはいけません。
こんな場合は、商品と自分の買い目の2本立てで馬券を買って下さい。
*ほとんどの皆様が、給料の他に1ヶ月で5万円から15万円位の
収入があれば、 生活が大変楽になると思います。
地道な必勝法ですが、現実的なものを開発いたしました。
よくお考え下さい。
ゆとりのある生活・・・
*申し訳ありませんが、無料で提供できる情報は以上です。
私の必勝法を商品化しましたので、是非購入をお勧めします。
*商品は予想ではありません、必勝本ですので無期限で使えます。
*必勝本販売が本職ではありませんので、下記の価格にしましたが
価値としては、金額に代えられないものと思います。
そこで、
1)私の必勝法は、誰でも納得でき女性の方でも安心してご利用頂けます。
2)96年上半期、JRA競馬開催144日の全レースを徹底分析致しました。
3)その上で、負けるのは5日だけと言いきれます。
4)投資金額のガイドラインも参考として提案してあります。
5)膨大なデータを基にある法則を発見し、さらに99%負けないように、
細かな点までフルサポートした競馬必勝法としての作品です。
6)手前味噌ですが、この作品の8000円は本当に安いと思います。
さあ、皆様もどうですか、私と同じく仕事を趣味として、
競馬で生活費を稼ぐ人生の仲間入りをしてみたいと思いませんか。
1)競馬もギャンブルなので、絶対という事ははあり得ません。
つまり、私の必勝法でも100%はありません。
2)具体的には、96年上半期(1月ー6月)中央競馬は、各地で144日
開催されましたが、全ての日に馬券を購入したとして、
負けるのは5日だけです、残りの139日は全て勝ちます。
つまり、私の必勝法の勝率は96.5%です。
「私は、自分の必勝法を94年位にほぼ完成させました、95年より
実際に試してみて、これはいけると確信いたしました。」
3)私の必勝法は、1万円が当日に20万円や30万円になるものでは
ありませんしかし、馬券購入当日は確実に勝ちます(96.5%)。
現実的には、1ヶ月(8日間)で8万円から20万円位のプラス
と考えて下さい。
4)競馬をやっている人は感じないと思いますが、
ゴールの瞬間の鼻差や首差のVIDEOを見て、
こんなのが当てられるハズがないと、
普通の人は感じます。
事実、皆様の廻りで1ヶ月(8日間)全日馬券を購入して、全日プラス
の人はいないと思います。
つまり、これは、基本的考え方に間違いがあると思われます。
5)パチンコのプロはいますが、競馬のプロはいません。
これは、騎手・血統・馬場状況・距離などを基にした従来の方法に、
大きな問題があると思われます。
6)皆様の中には、パチンコをしている人もいらっしゃるでしょう。
パチンコをしている人は、
パチンコの必勝法をほとんどの人が知っています。
つまり、 パチンコで勝つためには、
朝1からパチンコをしなくてはなりません。
夕方、会社が終わって6時頃から2-4時間打って毎日勝つ事は
不可能です。
たまには勝つかも知れませんが、ほとんど負けます。
この事を知っているのに、何故皆様は気づかないのでしょう、
そうです!
競馬も勝つためには、朝1からしなくてはなりません、
メインレースだけしていても勝てないのです。
7)スポーツ新聞等では、大穴や万馬券をどれだけ当てたかを
大々的に宣伝していますが、万馬券を当てようとして馬券を購入することは、
勝つ確率がかなり低いということです。
確率が低いのは低いのではなく、負ける事だと気づいて下さい。
負けるという事は、お金が無くなる事なのです。
馬券は、宝くじ感覚で買うものではありません。
◆競馬が飯より好きな方に一言◆
再三さいし注意してますが、皆さんは、予想や攻略法を買っても絶対に
自分の考えや買い目を入れてしまいます、こうすると、その予想や必勝法が
どの程度有効性のあるモノかが、分からなくなってしまいます、お金を出して
商品を買ってるのを忘れてはいけません。
こんな場合は、商品と自分の買い目の2本立てで馬券を買って下さい。
*ほとんどの皆様が、給料の他に1ヶ月で5万円から15万円位の
収入があれば、 生活が大変楽になると思います。
地道な必勝法ですが、現実的なものを開発いたしました。
よくお考え下さい。
ゆとりのある生活・・・
*申し訳ありませんが、無料で提供できる情報は以上です。
私の必勝法を商品化しましたので、是非購入をお勧めします。
*商品は予想ではありません、必勝本ですので無期限で使えます。
*必勝本販売が本職ではありませんので、下記の価格にしましたが
価値としては、金額に代えられないものと思います。
そこで、
1)私の必勝法は、誰でも納得でき女性の方でも安心してご利用頂けます。
2)96年上半期、JRA競馬開催144日の全レースを徹底分析致しました。
3)その上で、負けるのは5日だけと言いきれます。
4)投資金額のガイドラインも参考として提案してあります。
5)膨大なデータを基にある法則を発見し、さらに99%負けないように、
細かな点までフルサポートした競馬必勝法としての作品です。
6)手前味噌ですが、この作品の8000円は本当に安いと思います。
さあ、皆様もどうですか、私と同じく仕事を趣味として、
競馬で生活費を稼ぐ人生の仲間入りをしてみたいと思いませんか。
2010年8月24日火曜日
モバゲーでお小遣い稼ぎ【怪盗ロワイヤル編】
モバゲーを利用してお小遣い稼ぎが出来ることを
皆さんご存知でしょうか、以下の簡単な方法で月数万円程度は稼ぐことが可能です。
是非チャレンジしてみて下さいね
ちなみに出費は一切無いので安心して取り組むことが可能です。
ただし携帯電話のパケホーダイに入っておく事。
今から無職でも自宅に居ながらお金が稼げる方法を説明する。
難しい事があったら遠慮なく質問してくださいね。
まず、誰もが一度は聞いたことがあるであろう、携帯最大のサイト、モバゲータウンにアクセスする
【モバゲータウン】
今や2chやミクシィ以上にメジャーになったインターネットコミュニケーションサイト
40代50代のオッサンと小学生女児が出会える、まさに夢のようなサイト 『モバゲータウン』
日本最大規模の携帯サイトで、登録ユーザーは今年、男女合わせて1500万人を突破した
“200種類以上のゲームが無料で出来る”ことを歌い文句に宣伝しているが実情は援交や性交渉だらけの合法風俗と化している
全国の小学生~女子高生~OL~熟女 といったあらゆる年代の女を揃えている、まさに奇跡のようなサイト
↓まだ登録してない奴はこちらから登録(完全無料、個人情報いらない、いつでも退会可能)
怪盗ロワイヤル
【モバゲータウンを利用した金儲けの方法】
①まずモバゲーを始める(プロフィールは適当で良い)
②モバゲー内にある「怪盗ロワイヤル」というゲームを始める(テレビでもよくCM流れてる)
③怪盗ロワイヤルをやっている人は、全国70万人以上なので、この人口の多さを利用する
④怪盗ロワイヤルは、世界中のお宝を集めるゲームなのだが、お宝を集めるために必要なのが【武器】と【ワナ】
⑤いかに【武器】と【ワナ】を沢山持つかがこのゲームの攻略方法で、みんな必死に【武器】と【ワナ】を求めてる
⑥武器は強さによって値段が変わるのだが、ワナは3個100円で取り引きされている
⑦このワナを使用せず、集めるだけで、金儲けが出来る
⑧ワナを100個集めて取り引きに出せば、一気に3300円以上手に入る
⑨武器と一緒に取り引きすれば1万円以上手に入る
⑩毎日のように武器やワナを集めていけば、1ヶ月で10万円以上の収入が得られる
皆さんご存知でしょうか、以下の簡単な方法で月数万円程度は稼ぐことが可能です。
是非チャレンジしてみて下さいね
ちなみに出費は一切無いので安心して取り組むことが可能です。
ただし携帯電話のパケホーダイに入っておく事。
今から無職でも自宅に居ながらお金が稼げる方法を説明する。
難しい事があったら遠慮なく質問してくださいね。
まず、誰もが一度は聞いたことがあるであろう、携帯最大のサイト、モバゲータウンにアクセスする
【モバゲータウン】
今や2chやミクシィ以上にメジャーになったインターネットコミュニケーションサイト
40代50代のオッサンと小学生女児が出会える、まさに夢のようなサイト 『モバゲータウン』
日本最大規模の携帯サイトで、登録ユーザーは今年、男女合わせて1500万人を突破した
“200種類以上のゲームが無料で出来る”ことを歌い文句に宣伝しているが実情は援交や性交渉だらけの合法風俗と化している
全国の小学生~女子高生~OL~熟女 といったあらゆる年代の女を揃えている、まさに奇跡のようなサイト
↓まだ登録してない奴はこちらから登録(完全無料、個人情報いらない、いつでも退会可能)
怪盗ロワイヤル
【モバゲータウンを利用した金儲けの方法】
①まずモバゲーを始める(プロフィールは適当で良い)
②モバゲー内にある「怪盗ロワイヤル」というゲームを始める(テレビでもよくCM流れてる)
③怪盗ロワイヤルをやっている人は、全国70万人以上なので、この人口の多さを利用する
④怪盗ロワイヤルは、世界中のお宝を集めるゲームなのだが、お宝を集めるために必要なのが【武器】と【ワナ】
⑤いかに【武器】と【ワナ】を沢山持つかがこのゲームの攻略方法で、みんな必死に【武器】と【ワナ】を求めてる
⑥武器は強さによって値段が変わるのだが、ワナは3個100円で取り引きされている
⑦このワナを使用せず、集めるだけで、金儲けが出来る
⑧ワナを100個集めて取り引きに出せば、一気に3300円以上手に入る
⑨武器と一緒に取り引きすれば1万円以上手に入る
⑩毎日のように武器やワナを集めていけば、1ヶ月で10万円以上の収入が得られる
怪盗ロワイヤル
入金後、落札者様のIDとニックネームをお知らせください。
↓↓
こちらのニックネームをお知らせ後、友達希望いたしますので、申請を許可して下さい。
↓↓
受渡完了しましたら、こちらで仮退会致しますので、落札者様より仲間外しを行ってください。
↓↓
こちらのニックネームをお知らせ後、友達希望いたしますので、申請を許可して下さい。
↓↓
受渡完了しましたら、こちらで仮退会致しますので、落札者様より仲間外しを行ってください。
2010年8月21日土曜日
FireFoxをJavaScripで閉じる方法【window.close()有効化】
ウェブブラウザのFireFoxはJavaScriptからは閉じられないというのが定説ですが、
厳密にいうとこれは間違いです。
FireFoxがJavaScriptのWindow.close()で閉じられないのはセキュリティの設定が
高すぎることに起因しています。
そこでFireFoxをJavaScriptで閉じたいとお考えの方や
プログラム上で悩みを抱えていらっしゃるという方にお勧めしたいのが
ウェブブラウザFireFoxのセキュリティ設定を下げるという方法です。
やり方はいたって簡単で、すでにご存じの方もいらっしゃるとは思いますが、
FireForxのロケーションバーと呼ばれる通常URLを入力する場所に「about:config」と入力してください。
FireFoxの設定画面は特集でURLで移動することになっています。
about:configと入力すると警告メッセージが表示されますが、設定を変更する場合は
「最新の注意を払って使用する」というボタンをクリックしてください。
これはセキュリティ上のトラブルを避けるために表示されるものですが、
特別な操作をする以外の時は特に気にする必要はないと思います。
さて、次に表示される画面で様々な設定項目が表示されていることと思います、
一個一個説明していると時間がとても足りませんので、
ウィンドウを閉じる項目について説明をしたいと思います。
まずフィルタに「close」と入力して閉じる系の設定のみを表示させます。
すると
「allow_scripts_to_close_windows」という文字が含まれた項目が見つかると思います。
(あるいはdom.allow_scripts_to_close_windows)
英語が多少わかる方ならもう大丈夫ですね。
allow:許可する
scripts:スクリプト
close:閉じる
window:ウィンドウ
よってこの値をTrueと設定すればJavaScriptからWindowを閉じることが可能となります。
是非ご利用になられてみてはいかがでしょうか
厳密にいうとこれは間違いです。
FireFoxがJavaScriptのWindow.close()で閉じられないのはセキュリティの設定が
高すぎることに起因しています。
そこでFireFoxをJavaScriptで閉じたいとお考えの方や
プログラム上で悩みを抱えていらっしゃるという方にお勧めしたいのが
ウェブブラウザFireFoxのセキュリティ設定を下げるという方法です。
やり方はいたって簡単で、すでにご存じの方もいらっしゃるとは思いますが、
FireForxのロケーションバーと呼ばれる通常URLを入力する場所に「about:config」と入力してください。
FireFoxの設定画面は特集でURLで移動することになっています。
about:configと入力すると警告メッセージが表示されますが、設定を変更する場合は
「最新の注意を払って使用する」というボタンをクリックしてください。
これはセキュリティ上のトラブルを避けるために表示されるものですが、
特別な操作をする以外の時は特に気にする必要はないと思います。
さて、次に表示される画面で様々な設定項目が表示されていることと思います、
一個一個説明していると時間がとても足りませんので、
ウィンドウを閉じる項目について説明をしたいと思います。
まずフィルタに「close」と入力して閉じる系の設定のみを表示させます。
すると
「allow_scripts_to_close_windows」という文字が含まれた項目が見つかると思います。
(あるいはdom.allow_scripts_to_close_windows)
英語が多少わかる方ならもう大丈夫ですね。
allow:許可する
scripts:スクリプト
close:閉じる
window:ウィンドウ
よってこの値をTrueと設定すればJavaScriptからWindowを閉じることが可能となります。
是非ご利用になられてみてはいかがでしょうか
2010年8月18日水曜日
posgreSQL テーブルサンプル
-- Table: k_kind
-- DROP TABLE k_kind;
CREATE TABLE k_kind
(
"kindID" integer NOT NULL DEFAULT nextval('public."k_kind_kindID_seq"'::text),
"kNO" character(10),
"kindName" character varying(100),
CONSTRAINT kind_key PRIMARY KEY ("kindID")
)
WITHOUT OIDS;
ALTER TABLE k_kind OWNER TO postgres;
-- Table: kokyaku
-- DROP TABLE kokyaku;
CREATE TABLE kokyaku
(
"kID" integer NOT NULL DEFAULT nextval('public."kokyaku_kID_seq"'::text),
"name" character varying(255),
yubin character varying(100),
address character varying(255),
tel character varying(100),
kname character varying(255),
kind character(10),
CONSTRAINT kokyaku_key PRIMARY KEY ("kID")
)
WITHOUT OIDS;
ALTER TABLE kokyaku OWNER TO postgres;
-- DROP TABLE k_kind;
CREATE TABLE k_kind
(
"kindID" integer NOT NULL DEFAULT nextval('public."k_kind_kindID_seq"'::text),
"kNO" character(10),
"kindName" character varying(100),
CONSTRAINT kind_key PRIMARY KEY ("kindID")
)
WITHOUT OIDS;
ALTER TABLE k_kind OWNER TO postgres;
-- Table: kokyaku
-- DROP TABLE kokyaku;
CREATE TABLE kokyaku
(
"kID" integer NOT NULL DEFAULT nextval('public."kokyaku_kID_seq"'::text),
"name" character varying(255),
yubin character varying(100),
address character varying(255),
tel character varying(100),
kname character varying(255),
kind character(10),
CONSTRAINT kokyaku_key PRIMARY KEY ("kID")
)
WITHOUT OIDS;
ALTER TABLE kokyaku OWNER TO postgres;
JSPページ処理サンプル
String sql = "";
//ページ始★★★★★★★★★★★★★★★★★★★★★★★★★★
sql = "SELECT count(*) AS cnt FROM kokyaku";
ResultSet rc = dbab.getResultSet(sql);
int recMax = 5;
int cntAll = 0;//総レコード数
while (rc.next()) {
cntAll = rc.getInt("cnt");
}
cntAll += recMax;
int PageCnt = 0;//総ページ数
PageCnt = (cntAll / recMax);
String sNo = request.getParameter("pNo");
sNo = dbab.isNull(sNo, "0");
int PageNo = Integer.parseInt(sNo);
int iStart = recMax * PageNo;
int iEnd = recMax * (PageNo + 1);
/* 使用例 */
//int recCnt = 0;
//データ表示部
//while (rs.next()) {
// if((iStart <= recCnt) && (iEnd > recCnt)){
// }
// recCnt++;
//}
//リンク作成部
//for(int i = 1; i <= PageCnt; i++){ // out.print("" + i + "" + " /");
//}
//ページ終★★★★★★★★★★★★★★★★★★★★★★★★★★
//ページ始★★★★★★★★★★★★★★★★★★★★★★★★★★
sql = "SELECT count(*) AS cnt FROM kokyaku";
ResultSet rc = dbab.getResultSet(sql);
int recMax = 5;
int cntAll = 0;//総レコード数
while (rc.next()) {
cntAll = rc.getInt("cnt");
}
cntAll += recMax;
int PageCnt = 0;//総ページ数
PageCnt = (cntAll / recMax);
String sNo = request.getParameter("pNo");
sNo = dbab.isNull(sNo, "0");
int PageNo = Integer.parseInt(sNo);
int iStart = recMax * PageNo;
int iEnd = recMax * (PageNo + 1);
/* 使用例 */
//int recCnt = 0;
//データ表示部
//while (rs.next()) {
// if((iStart <= recCnt) && (iEnd > recCnt)){
// }
// recCnt++;
//}
//リンク作成部
//for(int i = 1; i <= PageCnt; i++){ // out.print("" + i + "" + " /");
//}
//ページ終★★★★★★★★★★★★★★★★★★★★★★★★★★
2010年8月17日火曜日
JSPでJavaBeansを利用するjsp:useBean
<jsp:useBean id="dbab" scope="page" class="datasource.DBAccessBean"></jsp:useBean>
2010年8月16日月曜日
javax.servlet.jsp.JspException: Bean actionform.Page6ActionForm のプロパティ value1 に対するゲッターメソッドがありません【解決方法】
Strutsの開発を行っていると、
「javax.servlet.jsp.JspException: Bean actionform.Page6ActionForm のプロパティ p1 に対するゲッターメソッドがありません」
というようなエラーが発生することがあります。
エラーメッセージの中に「ActionForm」と「p1に対するゲッターメソッド」という単語とが出ているため、
ActionFormクラスだけをみて解決しようとする方が多いようですが、
意外とJSP側にエラーの原因がある場合があります。
例えばhtml:textタグにvalue値を設定しておかないと発生します。
<html:text property="p1"></html:text>
これを以下のように修正すると発生しなくなります。
<html:text property="p1" value=""></html:text>
「javax.servlet.jsp.JspException: Bean actionform.Page6ActionForm のプロパティ p1 に対するゲッターメソッドがありません」
というようなエラーが発生することがあります。
エラーメッセージの中に「ActionForm」と「p1に対するゲッターメソッド」という単語とが出ているため、
ActionFormクラスだけをみて解決しようとする方が多いようですが、
意外とJSP側にエラーの原因がある場合があります。
例えばhtml:textタグにvalue値を設定しておかないと発生します。
<html:text property="p1"></html:text>
これを以下のように修正すると発生しなくなります。
<html:text property="p1" value=""></html:text>
2010年8月15日日曜日
発電機を自作してみよう【準備編】
発電機を自作してみようと思い立ったので
とりあえず道具をそろえてみましょう。
1、充電に使用するバッテリー
2、充電を行うチャージコントローラー
3、100V電気を取り出すインバーター
「動力を何にするか」は検討中です。
例)ソーラーパネル、ダイエット器具などなど
部品はすべて格安で揃えないといけないので、
新品で買うわけにはいきません。
時間がかかりますがオークションをメインに集める予定です。
部品がそろい次第、作成に取り掛かります。
とりあえず道具をそろえてみましょう。
1、充電に使用するバッテリー
2、充電を行うチャージコントローラー
3、100V電気を取り出すインバーター
「動力を何にするか」は検討中です。
例)ソーラーパネル、ダイエット器具などなど
部品はすべて格安で揃えないといけないので、
新品で買うわけにはいきません。
時間がかかりますがオークションをメインに集める予定です。
部品がそろい次第、作成に取り掛かります。
人気のわんわん日記: JSP/サーブレットで値の受け渡し【Struts】
人気のわんわん日記: JSP/サーブレットで値の受け渡し【Struts】: "今回はStrutsを利用してJSP/Servletによる値の受け渡し方法を説明します。 page5.jspからpage6.jspへの遷移をStrutsを用いて実施しています。 いつものように最後にstruts-config.xmlの追記を忘れないようにしましょう!! 1、pag..."
JSP/サーブレットで値の受け渡し【Struts】
今回はStrutsを利用してJSP/Servletによる値の受け渡し方法を説明します。
page5.jspからpage6.jspへの遷移をStrutsを用いて実施しています。
いつものように最後にstruts-config.xmlの追記を忘れないようにしましょう!!
1、page5.jspの作成
以前作成したpage5.jspに以下を追記
<html:form action="/page6" method="POST">
<html:text property="value1" name="value1" value=""></html:text>
<html:submit value="送信"></html:submit>
</html:form>
2、page6.jspの作成
ただ値を受け取るだけのページです。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<%= request.getParameter("value1") %>
<h1>page5.jspから送信された値</h1>
</body>
</html>
3、ActionFormクラスの作成
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package actionform;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
/**
*
* @author x300
*/
public class Page6ActionForm extends org.apache.struts.action.ActionForm {
private String name;
private int number;
/**
* @return
*/
public String getName() {
return name;
}
/**
* @param string
*/
public void setName(String string) {
name = string;
}
/**
* @return
*/
public int getNumber() {
return number;
}
/**
* @param i
*/
public void setNumber(int i) {
number = i;
}
/**
*
*/
public Page6ActionForm() {
super();
// TODO Auto-generated constructor stub
}
/**
* This is the action called from the Struts framework.
* @param mapping The ActionMapping used to select this instance.
* @param request The HTTP Request we are processing.
* @return
*/
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (getName() == null || getName().length() < 1) {
errors.add("name", new ActionMessage("error.name.required"));
// TODO: add 'error.name.required' key to your resources
}
return errors;
}
}
4、Actionクラスの作成
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
*
* @author x300
*/
public class Page6Action extends org.apache.struts.action.Action {
/* forward name="success" path="" */
private static final String SUCCESS = "success";
/**
* This is the action called from the Struts framework.
* @param mapping The ActionMapping used to select this instance.
* @param form The optional ActionForm bean for this request.
* @param request The HTTP Request we are processing.
* @param response The HTTP Response we are processing.
* @throws java.lang.Exception
* @return
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return mapping.findForward(SUCCESS);
}
}
5、suturuts-config.xmlに登録
ACTION-MAPPINGタグに追加するもの
<action input="/page6.jsp" name="Page6ActionForm" path="/page6" scope="session" type="action.Page6Action"/>
FORM-BEANSタグに追加するもの
<form-bean name="Page6ActionForm" type="actionform.Page6ActionForm"/>
page5.jspからpage6.jspへの遷移をStrutsを用いて実施しています。
いつものように最後にstruts-config.xmlの追記を忘れないようにしましょう!!
1、page5.jspの作成
以前作成したpage5.jspに以下を追記
<html:form action="/page6" method="POST">
<html:text property="value1" name="value1" value=""></html:text>
<html:submit value="送信"></html:submit>
</html:form>
2、page6.jspの作成
ただ値を受け取るだけのページです。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<%= request.getParameter("value1") %>
<h1>page5.jspから送信された値</h1>
</body>
</html>
3、ActionFormクラスの作成
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package actionform;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
/**
*
* @author x300
*/
public class Page6ActionForm extends org.apache.struts.action.ActionForm {
private String name;
private int number;
/**
* @return
*/
public String getName() {
return name;
}
/**
* @param string
*/
public void setName(String string) {
name = string;
}
/**
* @return
*/
public int getNumber() {
return number;
}
/**
* @param i
*/
public void setNumber(int i) {
number = i;
}
/**
*
*/
public Page6ActionForm() {
super();
// TODO Auto-generated constructor stub
}
/**
* This is the action called from the Struts framework.
* @param mapping The ActionMapping used to select this instance.
* @param request The HTTP Request we are processing.
* @return
*/
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (getName() == null || getName().length() < 1) {
errors.add("name", new ActionMessage("error.name.required"));
// TODO: add 'error.name.required' key to your resources
}
return errors;
}
}
4、Actionクラスの作成
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
*
* @author x300
*/
public class Page6Action extends org.apache.struts.action.Action {
/* forward name="success" path="" */
private static final String SUCCESS = "success";
/**
* This is the action called from the Struts framework.
* @param mapping The ActionMapping used to select this instance.
* @param form The optional ActionForm bean for this request.
* @param request The HTTP Request we are processing.
* @param response The HTTP Response we are processing.
* @throws java.lang.Exception
* @return
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return mapping.findForward(SUCCESS);
}
}
5、suturuts-config.xmlに登録
ACTION-MAPPINGタグに追加するもの
<action input="/page6.jsp" name="Page6ActionForm" path="/page6" scope="session" type="action.Page6Action"/>
FORM-BEANSタグに追加するもの
<form-bean name="Page6ActionForm" type="actionform.Page6ActionForm"/>
2010年8月14日土曜日
人気のわんわん日記: JSP/サーブレットでファイルをアップロードするには?
人気のわんわん日記: JSP/サーブレットでファイルをアップロードするには?: "JSP/サーブレットでファイルをアップロードするには、 従来は非常に煩雑なコーディングが必要となっていました。 そこで簡単にできるパッケージとしてJakarta Commons のサブプロジェクトにある upload.zip というjarファイルをlibに登録することで手軽に行う..."
JSP/サーブレットでファイルをアップロードするには?
JSP/サーブレットでファイルをアップロードするには、
従来は非常に煩雑なコーディングが必要となっていました。
そこで簡単にできるパッケージとしてJakarta Commons のサブプロジェクトにある
upload.zip というjarファイルをlibに登録することで手軽に行うことができるようになります。
動きとしてはJSPでファイルを選択してもらい、
サーブレットでWEB-INFのdataフォルダに保存するという処理になります。
1、JSPの作成
<%@ page contentType="text/html;charset=Windows-31J" %>
<html>
<head>
<title>ファイルのアップロード</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data"
action="UploadServlet">
ファイルパス:
<input type="file" name="fl" size="75" />
<input type="submit" value="アップロード" />
</form>
</body>
</html>
2、Servletの作成
package to.msn.wings.javatips;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
public class UploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request
, HttpServletResponse response)
throws ServletException, IOException {
String path=getServletContext().getRealPath("WEB-INF/data");
DiskFileUpload objDfu=new DiskFileUpload();
// アップロードファイルの最大サイズ(-1は無限)
objDfu.setSizeMax(-1);
// バッファサイズ
objDfu.setSizeThreshold(1024);
// 一時ファイルの保存先フォルダ
objDfu.setRepositoryPath(path);
// ヘッダの文字エンコーディング
objDfu.setHeaderEncoding("Windows-31J");
try {
// アップロードされたファイル情報を
// FileItemオブジェクトのリストとして取得
List objLst=objDfu.parseRequest(request);
Iterator objItr=objLst.iterator();
// リストから順にファイルデータを取り出し、
// 「/WEB-INF/data/元のファイル名」の形式で
// アップロードファイルを保存
while(objItr.hasNext()){
FileItem objFi=(FileItem)objItr.next();
if(!objFi.isFormField()){
// アップロードファイルの元ファイル名を取得
String strNam=objFi.getName();
if(strNam!=null && !strNam.equals("")){
strNam=(new File(strNam)).getName();
objFi.write(new File(path + "/" + strNam));
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// 処理後は元のupload.jspにリダイレクト
response.sendRedirect("upload.jsp");
}
従来は非常に煩雑なコーディングが必要となっていました。
そこで簡単にできるパッケージとしてJakarta Commons のサブプロジェクトにある
upload.zip というjarファイルをlibに登録することで手軽に行うことができるようになります。
動きとしてはJSPでファイルを選択してもらい、
サーブレットでWEB-INFのdataフォルダに保存するという処理になります。
1、JSPの作成
<%@ page contentType="text/html;charset=Windows-31J" %>
<html>
<head>
<title>ファイルのアップロード</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data"
action="UploadServlet">
ファイルパス:
<input type="file" name="fl" size="75" />
<input type="submit" value="アップロード" />
</form>
</body>
</html>
2、Servletの作成
package to.msn.wings.javatips;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
public class UploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request
, HttpServletResponse response)
throws ServletException, IOException {
String path=getServletContext().getRealPath("WEB-INF/data");
DiskFileUpload objDfu=new DiskFileUpload();
// アップロードファイルの最大サイズ(-1は無限)
objDfu.setSizeMax(-1);
// バッファサイズ
objDfu.setSizeThreshold(1024);
// 一時ファイルの保存先フォルダ
objDfu.setRepositoryPath(path);
// ヘッダの文字エンコーディング
objDfu.setHeaderEncoding("Windows-31J");
try {
// アップロードされたファイル情報を
// FileItemオブジェクトのリストとして取得
List objLst=objDfu.parseRequest(request);
Iterator objItr=objLst.iterator();
// リストから順にファイルデータを取り出し、
// 「/WEB-INF/data/元のファイル名」の形式で
// アップロードファイルを保存
while(objItr.hasNext()){
FileItem objFi=(FileItem)objItr.next();
if(!objFi.isFormField()){
// アップロードファイルの元ファイル名を取得
String strNam=objFi.getName();
if(strNam!=null && !strNam.equals("")){
strNam=(new File(strNam)).getName();
objFi.write(new File(path + "/" + strNam));
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// 処理後は元のupload.jspにリダイレクト
response.sendRedirect("upload.jsp");
}
人気のわんわん日記: データベース接続用JavaBeans
人気のわんわん日記: データベース接続用JavaBeans: "最終的にはコネクションをプールするデータソースクラスを目指します。 まずは接続とResultSetの返却用クラスを作成しました。 これを徐々に改良していきJSPからJavaBeansとして利用します。 /* * To change this template, choose ..."
データベース接続用JavaBeans
最終的にはコネクションをプールするデータソースクラスを目指します。
まずは接続とResultSetの返却用クラスを作成しました。
これを徐々に改良していきJSPからJavaBeansとして利用します。
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package datasource;
import java.sql.*;
public class DBAccessBean {
private String driver;
private String url;
private String user;
private String password;
private Connection connection;
private Statement statement;
private ResultSet resultset;
/**
* コンストラクタ
* @param driver ドライバー
* @param url URL
* @param user ユーザー名
* @param password パスワード
*/
public DBAccessBean(String driver, String url, String user, String password) {
this.driver = driver;
this.url = url;
this.user = user;
this.password = password;
}
/**
* 引数なしのコンストラクタ
* 既定値を使用する
*/
public DBAccessBean() {
driver = "org.postgresql.Driver";
url = "jdbc:postgresql:karte";
user = "postgres";
password = "momoco";
}
/**
* データベースへの接続を行う
*/
public synchronized void open() throws Exception {
Class.forName(driver);
connection = DriverManager.getConnection(url, user, password);
statement = connection.createStatement();
}
/**
* SQL 文を実行した結果の ResultSet を返す
* @param sql SQL 文
*/
public ResultSet getResultSet(String sql) throws Exception {
if ( statement.execute(sql) ) {
return statement.getResultSet();
}
return null;
}
/**
* SQL 文の実行
* @param sql SQL 文
*/
public void execute(String sql) throws Exception {
statement.execute(sql);
}
/**
* データベースへのコネクションのクローズ
*/
public synchronized void close() throws Exception {
if ( resultset != null ) resultset.close();
if ( statement != null ) statement.close();
if ( connection != null ) connection.close();
}
}
まずは接続とResultSetの返却用クラスを作成しました。
これを徐々に改良していきJSPからJavaBeansとして利用します。
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package datasource;
import java.sql.*;
public class DBAccessBean {
private String driver;
private String url;
private String user;
private String password;
private Connection connection;
private Statement statement;
private ResultSet resultset;
/**
* コンストラクタ
* @param driver ドライバー
* @param url URL
* @param user ユーザー名
* @param password パスワード
*/
public DBAccessBean(String driver, String url, String user, String password) {
this.driver = driver;
this.url = url;
this.user = user;
this.password = password;
}
/**
* 引数なしのコンストラクタ
* 既定値を使用する
*/
public DBAccessBean() {
driver = "org.postgresql.Driver";
url = "jdbc:postgresql:karte";
user = "postgres";
password = "momoco";
}
/**
* データベースへの接続を行う
*/
public synchronized void open() throws Exception {
Class.forName(driver);
connection = DriverManager.getConnection(url, user, password);
statement = connection.createStatement();
}
/**
* SQL 文を実行した結果の ResultSet を返す
* @param sql SQL 文
*/
public ResultSet getResultSet(String sql) throws Exception {
if ( statement.execute(sql) ) {
return statement.getResultSet();
}
return null;
}
/**
* SQL 文の実行
* @param sql SQL 文
*/
public void execute(String sql) throws Exception {
statement.execute(sql);
}
/**
* データベースへのコネクションのクローズ
*/
public synchronized void close() throws Exception {
if ( resultset != null ) resultset.close();
if ( statement != null ) statement.close();
if ( connection != null ) connection.close();
}
}
人気のわんわん日記: 【基本情報処理試験】アルゴリズムとプログラミング
人気のわんわん日記: 【基本情報処理試験】アルゴリズムとプログラミング: "JavaVMが稼働している環境だけあれば、 WebブラウザやWebサーバーが無くても動作するプログラムはどれか? ア:JavaScript イ:Javaアプリケーション ウ:Javaアプレット エ:Javaサーブレット 【解説】 ア:JavaScriptはJavaという文字が..."
【基本情報処理試験】アルゴリズムとプログラミング
JavaVMが稼働している環境だけあれば、
WebブラウザやWebサーバーが無くても動作するプログラムはどれか?
ア:JavaScript
イ:Javaアプリケーション
ウ:Javaアプレット
エ:Javaサーブレット
【解説】
ア:JavaScriptはJavaという文字が入っているが、
Java言語とは異なるものであります。
イ:Javaアプリケーション
これはJavaで作成されたアプリでJavaVMで稼働します。正解
ウ:Javaアプレット
Webブラウザや専用閲覧アプリで見られる
エ:Javaサーブレット
WebアプリでWebブラウザやWebサーバーが必要
WebブラウザやWebサーバーが無くても動作するプログラムはどれか?
ア:JavaScript
イ:Javaアプリケーション
ウ:Javaアプレット
エ:Javaサーブレット
【解説】
ア:JavaScriptはJavaという文字が入っているが、
Java言語とは異なるものであります。
イ:Javaアプリケーション
これはJavaで作成されたアプリでJavaVMで稼働します。正解
ウ:Javaアプレット
Webブラウザや専用閲覧アプリで見られる
エ:Javaサーブレット
WebアプリでWebブラウザやWebサーバーが必要
人気のわんわん日記: JSP(データベースPostgreSQ)サンプル
人気のわんわん日記: JSP(データベースPostgreSQ)サンプル: "<%@ page contentType='text/html; charset=Shift_JIS' %> <%@ page import='java.sql.*' %> <% Connection con = null; Statement stmt = null; try ..."
JSP(データベースPostgreSQ)サンプル
<%@ page contentType="text/html; charset=Shift_JIS" %>
<%@ page import="java.sql.*" %>
<%
Connection con = null;
Statement stmt = null;
try {
// ドライバクラスをロード
//Class.forName("org.gjt.mm.mysql.Driver");
Class.forName("org.postgresql.Driver"); // PostgreSQLの場合
// データベースへ接続
//String url = "jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS";
con =
DriverManager.getConnection("jdbc:postgresql:db001",
"postgres",
"zxcvvcxz"); // PostgreSQLの場合
//con = DriverManager.getConnection(url);
// ステートメントオブジェクトを生成
stmt = con.createStatement();
// 全ての行を検索するSQL文を作成
String sql = "SELECT * FROM tbl001";
// クエリーを実行して結果セットを取得
ResultSet rs = stmt.executeQuery(sql);
session.setAttribute("AAAA","FF");
%>
<html>
<head>
<title>JSPでDB接続</title>
</head>
<body>
<table border="1">
<tr>
<th>NO</th>
<th>言語</th>
<th>メッセージ</th>
</tr>
<%
// 検索された行数分ループ
while(rs.next()){
%>
<tr>
<td><%=rs.getInt("rid") %></td>
<td><%=rs.getString("username") %></td>
<td><%=rs.getString("username") %></td>
</tr>
<%
} // end while
%>
</table>
</body>
</html>
<%
} catch (Exception e) {
out.println("<font color=red><h3>エラー!</h3></font>" + e);
e.printStackTrace();
} finally {
// データベースへの接続をクローズします
try {
if (stmt!=null) {
stmt.close();
}
if (con!=null) {
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
%>
<%@ page import="java.sql.*" %>
<%
Connection con = null;
Statement stmt = null;
try {
// ドライバクラスをロード
//Class.forName("org.gjt.mm.mysql.Driver");
Class.forName("org.postgresql.Driver"); // PostgreSQLの場合
// データベースへ接続
//String url = "jdbc:mysql:///hellodb?useUnicode=true&characterEncoding=SJIS";
con =
DriverManager.getConnection("jdbc:postgresql:db001",
"postgres",
"zxcvvcxz"); // PostgreSQLの場合
//con = DriverManager.getConnection(url);
// ステートメントオブジェクトを生成
stmt = con.createStatement();
// 全ての行を検索するSQL文を作成
String sql = "SELECT * FROM tbl001";
// クエリーを実行して結果セットを取得
ResultSet rs = stmt.executeQuery(sql);
session.setAttribute("AAAA","FF");
%>
<html>
<head>
<title>JSPでDB接続</title>
</head>
<body>
<table border="1">
<tr>
<th>NO</th>
<th>言語</th>
<th>メッセージ</th>
</tr>
<%
// 検索された行数分ループ
while(rs.next()){
%>
<tr>
<td><%=rs.getInt("rid") %></td>
<td><%=rs.getString("username") %></td>
<td><%=rs.getString("username") %></td>
</tr>
<%
} // end while
%>
</table>
</body>
</html>
<%
} catch (Exception e) {
out.println("<font color=red><h3>エラー!</h3></font>" + e);
e.printStackTrace();
} finally {
// データベースへの接続をクローズします
try {
if (stmt!=null) {
stmt.close();
}
if (con!=null) {
con.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
%>
人気のわんわん日記: org.apache.struts.Globals.DATA_SOURCE_KEYエラー
人気のわんわん日記: org.apache.struts.Globals.DATA_SOURCE_KEYエラー: "Strutsからデータベースを使用してみようと org.apache.struts.Globals.DATA_SOURCE_KEY をクラス内に記述したところ「Globals.DATA_SOURCE_KEY が 解決できません。」という エラーが発生するようになってしまいました。..."
org.apache.struts.Globals.DATA_SOURCE_KEYエラー
Strutsからデータベースを使用してみようと
org.apache.struts.Globals.DATA_SOURCE_KEY
をクラス内に記述したところ「Globals.DATA_SOURCE_KEY が 解決できません。」という
エラーが発生するようになってしまいました。
Strutsからデータベースへ接続する場合、
struts-config.xmlにデータソースを定義する方法がありますが、
実はこれ、推奨されてない方法らしく今では使えなくなっているとのこと。
となると、自前でデータソースを定義するのがベストかな。
org.apache.struts.Globals.DATA_SOURCE_KEY
をクラス内に記述したところ「Globals.DATA_SOURCE_KEY が 解決できません。」という
エラーが発生するようになってしまいました。
Strutsからデータベースへ接続する場合、
struts-config.xmlにデータソースを定義する方法がありますが、
実はこれ、推奨されてない方法らしく今では使えなくなっているとのこと。
となると、自前でデータソースを定義するのがベストかな。
人気のわんわん日記: Struts Apache2.2 Tomcat5.5 連携基礎
人気のわんわん日記: Struts Apache2.2 Tomcat5.5 連携基礎: "Strutsを利用してURLが*.doで次ページに戻るアプリです。 とりあえず動くものをアップしておきます。 ------------------------------------------------------------------------------------..."
Struts Apache2.2 Tomcat5.5 連携基礎
Strutsを利用してURLが*.doで次ページに戻るアプリです。
とりあえず動くものをアップしておきます。
-----------------------------------------------------------------------------------------
■JSPページ作成
page4.jsp
-----------------------------------------------------------------------------------------
<%--
Document : page4
Created on : 2010/08/14
Author : springjoe2
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!-- タグライブラリ設定 -->
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test4JSP</title>
</head>
<body>
<h1>テスト4JSP</h1>
<html:link action="/page4action">自分に戻る</html:link>
</body>
</html>
---------------------------------------------------------------------------------------
■アクションクラス作成
Page4Action.java
---------------------------------------------------------------------------------------
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
*
* @author x300
*/
public class Page4Action extends org.apache.struts.action.Action {
/* forward name="success" path="" */
private static final String SUCCESS = "success";
/**
* This is the action called from the Struts framework.
* @param mapping The ActionMapping used to select this instance.
* @param form The optional ActionForm bean for this request.
* @param request The HTTP Request we are processing.
* @param response The HTTP Response we are processing.
* @throws java.lang.Exception
* @return
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return mapping.findForward(SUCCESS);
}
}
---------------------------------------------------------------------------------------
■アクションフォームクラス作成
Page4ActionForm.java
---------------------------------------------------------------------------------------
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package actionform;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
/**
*
* @author x300
*/
public class Page4ActionForm extends org.apache.struts.action.ActionForm {
private String name;
private int number;
/**
* @return
*/
public String getName() {
return name;
}
/**
* @param string
*/
public void setName(String string) {
name = string;
}
/**
* @return
*/
public int getNumber() {
return number;
}
/**
* @param i
*/
public void setNumber(int i) {
number = i;
}
/**
*
*/
public Page4ActionForm() {
super();
// TODO Auto-generated constructor stub
}
/**
* This is the action called from the Struts framework.
* @param mapping The ActionMapping used to select this instance.
* @param request The HTTP Request we are processing.
* @return
*/
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (getName() == null || getName().length() < 1) {
errors.add("name", new ActionMessage("error.name.required"));
// TODO: add 'error.name.required' key to your resources
}
return errors;
}
}
-----------------------------------------------------------------------------------------
■いつものように最後にstruts-config.xmlを変更
<action-mappings>の<action path="/Welcome" forward="/page4.jsp"/>ウェルカムページ
1、forward4のkeyでpage4.jspへ飛ぶ
<global-forwards>の<forward name="forward4" path="/page4.jsp"/>
2、アクションマッピングpage4.jspへ飛ぶというアクション
<action input="/page4.jsp" name="Page4ActionForm" path="/page4action" scope="session" type="action.Page4Action"/>
とりあえず動くものをアップしておきます。
-----------------------------------------------------------------------------------------
■JSPページ作成
page4.jsp
-----------------------------------------------------------------------------------------
<%--
Document : page4
Created on : 2010/08/14
Author : springjoe2
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!-- タグライブラリ設定 -->
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test4JSP</title>
</head>
<body>
<h1>テスト4JSP</h1>
<html:link action="/page4action">自分に戻る</html:link>
</body>
</html>
---------------------------------------------------------------------------------------
■アクションクラス作成
Page4Action.java
---------------------------------------------------------------------------------------
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
*
* @author x300
*/
public class Page4Action extends org.apache.struts.action.Action {
/* forward name="success" path="" */
private static final String SUCCESS = "success";
/**
* This is the action called from the Struts framework.
* @param mapping The ActionMapping used to select this instance.
* @param form The optional ActionForm bean for this request.
* @param request The HTTP Request we are processing.
* @param response The HTTP Response we are processing.
* @throws java.lang.Exception
* @return
*/
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return mapping.findForward(SUCCESS);
}
}
---------------------------------------------------------------------------------------
■アクションフォームクラス作成
Page4ActionForm.java
---------------------------------------------------------------------------------------
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package actionform;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
/**
*
* @author x300
*/
public class Page4ActionForm extends org.apache.struts.action.ActionForm {
private String name;
private int number;
/**
* @return
*/
public String getName() {
return name;
}
/**
* @param string
*/
public void setName(String string) {
name = string;
}
/**
* @return
*/
public int getNumber() {
return number;
}
/**
* @param i
*/
public void setNumber(int i) {
number = i;
}
/**
*
*/
public Page4ActionForm() {
super();
// TODO Auto-generated constructor stub
}
/**
* This is the action called from the Struts framework.
* @param mapping The ActionMapping used to select this instance.
* @param request The HTTP Request we are processing.
* @return
*/
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (getName() == null || getName().length() < 1) {
errors.add("name", new ActionMessage("error.name.required"));
// TODO: add 'error.name.required' key to your resources
}
return errors;
}
}
-----------------------------------------------------------------------------------------
■いつものように最後にstruts-config.xmlを変更
<action-mappings>の<action path="/Welcome" forward="/page4.jsp"/>ウェルカムページ
1、forward4のkeyでpage4.jspへ飛ぶ
<global-forwards>の<forward name="forward4" path="/page4.jsp"/>
2、アクションマッピングpage4.jspへ飛ぶというアクション
<action input="/page4.jsp" name="Page4ActionForm" path="/page4action" scope="session" type="action.Page4Action"/>
登録:
投稿 (Atom)