POIでEXCELを操作してみる

javaでExcelに値を書き込むためにPOIを使用してみます。

POIをGET

このプログラムを作成したころはpoiの2.5だったのですが、現在では3.8が利用できるようです。何が変わったのかは未確認。

wget	http://ftp.riken.jp/net/apache/poi/release/bin/poi-bin-3.8-20120326.tar.gz
tar zxvfp poi-bin-3.8-20120326.tar.gz

この中のpoi-3.8-20120326.jarが本体となります

仕様

Excelに書き込むためにはあらかじめテンプレートを用意しておきその中にプログラムから値を書き込む仕様にします。

まずテンプレート用にtemplate.xlsを作成します

新規ファイルを作成し、B4に[a1]、B6に[a2]、D6に[e0-1]を記入しxls形式(2003までの形式)で保存。

サンプルプログラム

  • ExcelCellData.java
import java.util.GregorianCalendar;

import org.apache.poi.hssf.usermodel.HSSFCell;

/** セルに書き込むデータを保持するクラス */
public class ExcelCellData{
 public static int DOUBLE=1;
 public static int STRING=2;
 public static int CALENDAR=3;
 private int m_col;
 private int m_row;
 private int m_type;
 private Object m_val;
 private short m_enc;
 private int m_obj;

 /** コンストラクタ
	 @param col エクセルシートの行
	 @param row エクセルシートの列
	 @param val 書き込むデータ String or GregorianCalendar or double */
 public ExcelCellData(int col,int row,Object val){
	 m_col=col;
	 m_row=row;
	 if(val instanceof String){
		 m_type=HSSFCell.CELL_TYPE_STRING;
		 m_enc=HSSFCell.ENCODING_UTF_16;
		 m_obj=STRING;
	 }else if(val instanceof GregorianCalendar){
		 m_type=HSSFCell.CELL_TYPE_STRING;
		 m_enc=HSSFCell.ENCODING_COMPRESSED_UNICODE;
		 m_obj=CALENDAR;
	 }else{
		 m_type=HSSFCell.CELL_TYPE_NUMERIC;
		 m_enc=HSSFCell.ENCODING_COMPRESSED_UNICODE;
		 m_obj=DOUBLE;
	 }
	 m_val=val;
 }

 /** セルに書き込むデータのセル行を得る
	 @return 行番号 */
 public int getCol(){return m_col;}
 /** セルに書き込むデータのセル列を得る
	 @return 列番号 */
 public int getRow(){return m_row;}
 /** セルに書き込むデータの値を得る
	 @return 値 */
 public Object getCellValue(){return m_val;}
 /** セルに書き込むデータのタイプを得る
	 @return */
 public int getCellType(){return m_type;}
 /** セルに書き込むデータのエンコードタイプを得る
	 @return */
 public short getCellEncoding(){return m_enc;}
 /** セルに書き込むデータの種類を得る
	 @return ExcelData.Cell.DOUBLE,ExcelDat.Cell.STRING,ExcelData.Cell.CALENDAR	*/
 public int getObjectType(){return m_obj;}
}
  • ExcelData.java
import java.util.Calendar;
import java.util.Date;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
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.hssf.util.HSSFColor;

 /**
	 Excel に書き込むデータを保持する
 */
 public class ExcelData {
	 private HSSFWorkbook m_wb;
	 private HSSFSheet hsheet;
	 private HSSFRow hrow;
	 private HSSFCell hcell;
 
	 /** コンストラクタ */
	 public ExcelData(){
		 m_wb=new HSSFWorkbook();
	 }
 
	 public ExcelData(HSSFWorkbook wb){
		 m_wb=wb;
	 }
 
	 public void addData(String sheet,int col,int row,String val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(String sheet,int col,int row,String val,
		 int top,int bottom,int left,int right){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート名
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ
		 @param color 色 */
	 public void addData(String sheet,int col,int row,String val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
 
 
	 public void addData(String sheet,int col,int row,boolean val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(String sheet,int col,int row,boolean val,
		 int top,int bottom,int left,int right ){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート名
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ 
		 @param color 色 */
	 public void addData(String sheet,int col,int row,boolean val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
 
 
	 public void addData(String sheet,int col,int row,Calendar val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(String sheet,int col,int row,Calendar val,
		 int top,int bottom,int left,int right ){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート名
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ
		 @param color 色 */
	 public void addData(String sheet,int col,int row,Calendar val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
 
	 public void addData(String sheet,int col,int row,double val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(String sheet,int col,int row,double val,
		 int top,int bottom,int left,int right ){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート名
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ 
		 @param color 色 */
	 public void addData(String sheet,int col,int row,double val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
	 public void addData(String sheet,int col,int row,Date	 val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(String sheet,int col,int row,Date	 val,
		 int top,int bottom,int left,int right ){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート名
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ
		 @param color 色 */
	 public void addData(String sheet,int col,int row,Date val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
 
	 public void addData(int sheet,int col,int row,String val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(int sheet,int col,int row,String val,
		 int top,int bottom,int left,int right){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ
		 @param color 色 */
	 public void addData(int sheet,int col,int row,String val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
 
 
	 public void addData(int sheet,int col,int row,boolean val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(int sheet,int col,int row,boolean val,
		 int top,int bottom,int left,int right ){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ 
		 @param color 色 */
	 public void addData(int sheet,int col,int row,boolean val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
 
 
	 public void addData(int sheet,int col,int row,Calendar val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(int sheet,int col,int row,Calendar val,
		 int top,int bottom,int left,int right ){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ
		 @param color 色 */
	 public void addData(int sheet,int col,int row,Calendar val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
 
	 public void addData(int sheet,int col,int row,double val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(int sheet,int col,int row,double val,
		 int top,int bottom,int left,int right ){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ 
		 @param color 色 */
	 public void addData(int sheet,int col,int row,double val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
	 public void addData(int sheet,int col,int row,Date	 val){
		 addData(sheet,col,row,val,0,0,0,0);
	 }
	 public void addData(int sheet,int col,int row,Date	 val,
		 int top,int bottom,int left,int right ){
		 addData(sheet,col,row,val,top,bottom,left,right,(short)0);
	 }
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート
		 @param col 行
		 @param row 列
		 @param val 値
		 @param top 罫線フラグ
		 @param bottom 罫線フラグ
		 @param left 罫線フラグ
		 @param right 罫線フラグ
		 @param color 色 */
	 public void addData(int sheet,int col,int row,Date val,
		 int top,int bottom,int left,int right,short color ){
		 getcell(sheet,col,row);
		 hcell.setCellValue(val);
		 setstyle(bottom,top,left,right,color);
	 }
 
	 /** エクセルに書き込むセル単位のデータを追加
		 @param sheet シート
		 @param col 行
		 @param row 列
		 @param val 値 
		 @param style */
	 public void addData(int sheet,int col,int row,Object val,HSSFCellStyle style){
		 getcell(sheet,col,row);
		 if(val instanceof Boolean){
			 hcell.setCellValue(((Boolean)val).booleanValue());
		 }else if(val instanceof Calendar){
			 hcell.setCellValue((Calendar)val);
		 }else if(val instanceof Date){
			 hcell.setCellValue((Date)val);
		 }else if(val instanceof Double){
			 hcell.setCellValue(((Double)val).doubleValue());
		 }else if(val instanceof String){
			 hcell.setCellType(HSSFCell.CELL_TYPE_STRING);
			 //hcell.setEncoding(HSSFCell.ENCODING_UTF_16);
			 hcell.setCellValue((String)val);
			 if(((String)val).indexOf("\n")>=0){
				 style.setWrapText(true);
			 }
		 }
		 setstyle(style);
	 }
 
 
	 private void getcell(String sheet,int col,int row){
		 if(m_wb.getSheetIndex(sheet)<0){
			 hsheet=m_wb.createSheet(sheet);
		 }else{
			 hsheet=m_wb.getSheet(sheet);
		 }
		 hrow=hsheet.getRow((short)row);
		 if(hrow==null){
			 hrow=hsheet.createRow((short)row);
		 }
		 hcell=hrow.getCell(col);
		 if(hcell==null){
			 hcell=hrow.createCell(col);
		 }
	 }
	 private void getcell(int sheet,int col,int row){
		 hsheet=m_wb.getSheetAt(sheet);
		 if(hsheet==null){
			 hsheet=m_wb.createSheet();
		 }
		 hrow=hsheet.getRow((short)row);
		 if(hrow==null){
			 hrow=hsheet.createRow((short)row);
		 }
		 hcell=hrow.getCell(col);
		 if(hcell==null){
			 hcell=hrow.createCell(col);
		 }
	 }
 
	 private void setstyle(HSSFCellStyle style){
		 hcell.setCellStyle(style);
	 }
 
	 private void setstyle(int bottom,int top,int left,int right,
		 short color){
		 HSSFCellStyle style =m_wb.createCellStyle();
		 if(bottom>0){
			 if(bottom==1){
				 style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
				 style.setBottomBorderColor(HSSFColor.BLACK.index);
			 }
		 }
		 if(left>0){
			 style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
			 style.setLeftBorderColor(HSSFColor.BLACK.index);
		 }
		 if(right>0){
			 style.setBorderRight(HSSFCellStyle.BORDER_THIN);
			 style.setRightBorderColor(HSSFColor.BLACK.index);
		 }
		 if(top>0){
			 style.setBorderTop(HSSFCellStyle.BORDER_THIN);
			 style.setTopBorderColor(HSSFColor.BLACK.index);
		 }
		 if(color>0){
			 style.setFillForegroundColor(color);
			 style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		 }
		 hcell.setCellStyle(style);
	 }
	 
	 public HSSFWorkbook get(){
		 return m_wb;
	 }
 }

  • ExcelSheetData.java
import java.util.Enumeration;
import java.util.Vector;

/**
	ExcelSheet に書き込むデータを保持する
*/
public class ExcelSheetData implements Enumeration{
 private Vector m_dat;
 private int m_cnt;
 private String m_sheet;	/* シート名 */

 /** コンストラクタ
	@param sheet シート名
 */
 public ExcelSheetData(String sheet){
	 m_sheet=sheet;
	 m_cnt=0;
	 m_dat=new Vector();
 }

 /** エクセルに書き込むセル単位のデータを追加する
	 @param cell セルデータ */
 public void addData(ExcelCellData cell){
	 m_dat.add(cell);
 }

 public boolean hasMoreElements(){
	 if(m_cnt
  • ExcelCreator.java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Hashtable;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
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;

 /** エクセルに書き込む */
 public class ExcelCreator {
	 private static String TEMPLATE="template.xls";	 
	 private String m_template;
	 private String m_file;
	 private ExcelData m_edat;
 
	 /** コンストラクタ
		 @param file ファイル名 */
	 public ExcelCreator(String file){
		 m_file=file;
		 m_template=TEMPLATE;
	 }
 
	 /**
		 @param template 雛形ファイル名
		 @param file ファイル名 */
	 public ExcelCreator(String template,String file){
		 m_file=file;
		 m_template=template;
	 }
 
	 public void create(ExcelData edat) throws Exception{ 
		 m_edat=edat;
		 try{
			 HSSFWorkbook wb=m_edat.get();
 
			 FileOutputStream fileOut = new FileOutputStream(m_file);
			 wb.write(fileOut);
			 fileOut.close();
		 }catch(Exception e){
			 throw e;
		 }
	 }
 
 
	 public	HSSFWorkbook read(){
		 HSSFWorkbook wb=null;
		 try{
			 POIFSFileSystem fs			=
				 new POIFSFileSystem(new FileInputStream(m_template));
			 wb = new HSSFWorkbook(fs);
		 }catch(Exception e){
			 e.printStackTrace();
			 wb=new HSSFWorkbook();
		 }
		 return wb;
	 }
 
 
	 /** テンプレートのデータを実際のデータに置き換える
		 @param wb
		 @param dat key:[key],val:value 
		 @return */
	 public ExcelData createdata(HSSFWorkbook wb,Hashtable dat){
		 HSSFSheet sheet=null;
		 HSSFRow row=null;
		 HSSFCell cell=null;
		 int sheet_max=0;
 
		 ExcelData ed=new ExcelData(wb);
		 for(int ii=0;ii=wb.getNumberOfSheets())break;
			 sheet=wb.getSheetAt(ii);
			 if(sheet==null)continue;
 
			 for(int jj=sheet.getFirstRowNum();jj<=sheet.getLastRowNum();jj++){
				 row=sheet.getRow(jj);
				 if(row==null)continue;
				 
				 for(int kk=row.getFirstCellNum();kk<=row.getLastCellNum();kk++){
					 cell=row.getCell(kk);
					 if(cell==null)continue;
 
					 String key=keycheck(cell.getStringCellValue());
					 HSSFCellStyle style=cell.getCellStyle();
					 if(key!=null){
						 Object val=dat.get(key);
						 if(val==null){
							 String wk="";
							 val=(Object)wk;
						 }
							ed.addData(ii,kk,jj,val,style);
					 }
				 }
			 }
			 sheet_max++;
		 } 
		 return ed;
	 }
 
	 private String keycheck(String key){
		 String ret=null;
		 if(key!=null && !key.trim().equals("")){
			 String wk=key.trim();
			 if(wk.indexOf("[")==0 && wk.indexOf("]")==wk.length()-1){
				 ret=wk.substring(1,wk.length()-1);
			 }
		 }
		 return ret;
	 }

 
	 public static void main(String[] args) throws Exception {
		 ExcelCreator ec=new ExcelCreator("template.xls","output.xls");
		 Hashtable dat=new Hashtable();
		 dat.put("a1","aaa");
		 dat.put("a2",new Double(2));
		 dat.put("e0-1","niao \n 1000 \n 日本語");
		 ExcelData ed=ec.createdata(ec.read(),dat);
		 try{
			 ec.create(ed);
		 }catch(Exception e){
			 e.printStackTrace();
		 }
	 }
 }

実行

poi-3.8-20120326.jarにCLASSPATHを通してExcelCreatorを実行します。template.xlsは同じディレクトリに入れておきます。

output.xlsというファイルが作成され、templateで指定したセルの部分に値が入っているのがわかります