Create  Edit  Diff  FrontPage  Index  Search  Changes  Login

The Backyard - JakartaPoi Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

日記から転載

!2004-11-28 POIメモ

POIをいきなり見に行くと複合文書についていろいろ書いてある。でも、やりたいことは単にExcelで処理可能な、でもCSVやタブ区切りではないファイルの作成だったり(拡張子がxlsのやつ)。

で、そのドキュメントを探すのにちょっと苦労したり。だって複合文書用のファイルシステムがやたらと多いから。で見つけて使ってみるといきなり日本語が正しく表示されなかったり。

というわけでとりあえずシート名を日本語にし、セル内に日本語を埋め込むサンプルのメモ。

import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class PoiTest {
     static void setData(HSSFSheet s, int n) {
         for (int i = 0; i < n; i++) {
             HSSFRow r = s.createRow(i);
             for (int j = 0; j < 8; j++) {
                 HSSFCell c = r.createCell((short)j);
                 c.setEncoding(HSSFCell.ENCODING_UTF_16);
                 c.setCellValue((n % 2 == 1) ? "漢字のテキスト" : "abc");
             }
             HSSFCell c = r.createCell((short)8);
             c.setCellValue(i);
         }
     }
  
     public static void main(String[] args) throws Exception {
         HSSFWorkbook hw = new HSSFWorkbook();
         HSSFSheet st = hw.createSheet();
         hw.setSheetName(0, "日本語", HSSFWorkbook.ENCODING_UTF_16);
         st.setColumnWidth((short)0, (short)(256 * 12));
         setData(st, 11);
         st = hw.createSheet("English");
         setData(st, 20);
         FileOutputStream fo = new FileOutputStream("test.xls");
         hw.write(fo);
         fo.close();
     }
}

で、

$ javac -encoding Windows-31J -classpath poi-2.5.1-final-20040804.jar PoiTest.java
$ java -cp .:poi-2.5.1-final-20040804.jar PoiTest
$

!! 0から始めるか1からやるか

POIは0から始まる。これはJavaの配列のインデックスとも一致している。

しかし、VBAの配列のインデックスは本当は1から始めるのが文法を作った人の意図のはず。だからExcelを初めとしたOffice系のオートメーションではインデクサの引数は1から始まるのではないだろうか。

というかExcelそのもののロウが1から始まってるからかも。0じゃないよ。表計算ソフトの行表示としても1と書いてあるのは多分、正しい(しょせん多分に過ぎないけど。しかし自然数を採用するのは自然ではあると思う)。

だからVBAでの(というかCOMで表されているExcelのAPIとしての)Cells(1,1)というのは、POIのRow=0、Cell=0 になるのだが、これってどうなのかな。少なくてもRange("A1")というのは判りやすいし、そこからCells(1, 1)もわかりにくくは無いような気もする。とすればPOIがわかりにくいということだ。でも、最初から0として試し始めていたから直観的なのかも知れないけど、わからん。

同じJavaのAPIでもJDBCは1から始めてる。これはとってもイヤで、getString(0)とか書いて実行時に例外を食らったことが無いわけでは無い。とは言え、SQLの発想としては正しいのかな、と思うし、(実はADOは知っているけどODBCは知らないし、今更調べても役に立たないから調べないけど)多分ODBCも1から始めてるんじゃなかろうか。

っていうか調べてしまった。

""ColumnNumber
""
""[Input]
""
""Number of the column for which to return data. Result set columns are numbered in increasing column order starting at 1. The bookmark column is column number 0; this can be specified only if bookmarks are enabled.
""
――SQLGetDataのAPIリファレンスから引用

そうかカラム番号なのか。なら、1から始まるのはExcelのセルと同じで(多分)正しい発想だろう。

このあたりがPOIの注意点かな。Excelのオブジェクトモデルとは全然異なるということで。