はじめに
以前、私はある職場で、新たに提起された要求に対して可能な解決策を列挙して格付けするという大変愉快な仕事をしていました(その手の仕事を楽しむマゾヒスト的な面が私には確かにあります)。その中に、「BIポータルアプリケーションの完全ポータブル版の開発」という要求がありました。非技術系ユーザーのノートPCから実行でき、Excel経由でデータをリアルタイムで更新できるようにするという条件でした。この要求はある技術担当役員から出されたもので、その役員によると、彼がBIポータルアプリケーションを提案するために静的なHTMLのデモを見せると顧客からは大抵消極的な反応が返ってくるが、それは主としてデモで使われているデータが古く、そのせいでアプリケーション本来のメリットに目が向かわないからだというのです。
ここで必要とされるソリューションを具体的に挙げると、まずアプリケーションサーバーに関する知識を持たない技術担当役員のノートPCから実行できるWebアプリケーションが必要です。また、Excelファイルをデータソースとして簡単に読み込むことができなければなりません。さらに、できればデータをリアルタイムで更新することも求められます。この最初の部分は、私が仕事の合間に作成したあるアプリケーションで解決されました(Open Source-Based Portal-Liteを参照)。残るはExcelファイルの読み込み機能でした。これに関してはオープンソースと商用の両方のソリューションがあることが分かりました。しかし、今回開発するのはアプリケーション販促のためのアプリケーションであり、予算に限りがあるため、商用ソリューションの方はすぐ候補リストの一番最後に入れられました。オープンソースのアプリケーションの中で評価的に傑出していたのは、Apache POI HSSF APIでした。
Apache POIプロジェクトは、Microsoft Officeファイルの読み込みと書き出しを実現するJava APIの集合体です。Java EEによるWebアプリケーションは主としてデータベースのブラウザインターフェースの構築に用いられます。Microsoft Officeに関してはさまざまな意見があると思いますが、職場の至るところで利用されており、ネットワーク上やスモールビジネスPC上に大量のデータがExcelファイルとして格納されていることは紛れもない事実です。
ExcelファイルのデータからJavaオブジェクトを生成する
最初のステップでは、Excelファイルを直接読み取り、それをJavaで扱えるデータに変換します。これはPOIFSFileSystem
オブジェクトとHSSFWorkbook
オブジェクトを生成することで実現されます。HSSFWorkbook
オブジェクトはルートオブジェクトであり、そこからExcelファイルの各部分にアクセスします。
本稿では、Excelをデータベースとして利用するアプリケーションのサンプルクラスを修正して使いました。このクラスでは静的コンストラクタに対する引数としてファイルパスが使われています。
public static ExcelReader getInstance(String sDocPath) throws IOException { return new ' ExcelReader(sDocPath); }
次に、POIFSFileSystem
およびHSSFWorkbook
オブジェクトを初期化するためにプライベートコンストラクタが呼び出されます。
private ExcelReader(String sDocPath) throws IOException { this.instance = new ExcelReader(); this.docPath = sDocPath; this.document = new POIFSFileSystem(new FileInputStream(docPath)); this.workbook = new HSSFWorkbook(document); }
ExcelファイルがアップロードされるWebアプリケーションでは、アップロードを扱うためにどのような機構を用意するにしても、java.io.InputStream
を生成するのが常套手段です。例えば、Struts 1.xアプリケーションでは、org.apache.struts.upload.FormFile
インターフェースのgetInputStream()
メソッドを使用してPOIFSFileSystemコンストラクタのパラメータを提供します。
どちらにしても、大量のHSSF APIを独自のクラスで抽象化して、アプリケーションで必要とされる重要なメソッドだけに集中できるようにすることはよいことです。例えば、上記のコンストラクタでPOIFSFileSystem
オブジェクトとHSSFWorkbook
オブジェクトを生成しているのは、このクラスのクライアントがExcelファイルから値を読み込むことにしか関心がなく、POIFSFileSystem
クラスを使えばExcelの読み込みと書き出しの両方を実現できるからです。