連載
» 2008年08月18日 00時00分 公開

XMLを取り込んだ最新Officeフォーマットとは(後編):最新ExcelフォーマットをJavaで操作するための基礎 (2/2)

[Girier陽子,株式会社 東芝 ソフトウェア技術センター]
前のページへ 1|2       

DOMでExcelファイルを参照・更新・削除するには?

 それでは、Java標準のDOM操作APIを利用して「sample.xlsx」に含まれるsheet1.xmlの内容を解析します。ダウンロードして解凍したフォルダの中から、テキストエディタで「OXMLEditor.java」ファイルを開いてください。OXMLEditor.javaの処理の流れは、次のようになります。

27 oxml.unzip("sample.xlsx"); /* sample.xlsxの解凍 */
28 document = oxml.read(
       "xl/worksheets/sheet1.xml"); /* sheet1.xmlの読み込み */
29
30 oxml.showData(); /* Excelファイルデータ表示 */
31 oxml.insertData(2, "新製品名2", 2, 500); /* 2行目挿入 */
32 oxml.updateData(3, "製品名3", 10, 1200); /* 3行目更新 */
33 oxml.showData(4); /* 4行目データ表示 */
34 oxml.deleteData(4); /* 4行目削除 */
35 oxml.insertData("製品名4", 4, 2000); /* 行追加 */
36 oxml.showData(); /* Excelファイルデータ表示 */
37
   /* sheet1.xml生成 */
38 oxml.saveDocument("xl/worksheets/sheet1.xml",document);
   /* sample.xlsx生成 */      
39 oxml.createZIPfile(fileList,"sample.xlsx");

1.Excelファイル「sample.xlsx」の解凍(27行目)

2.解凍されたsheet1.xmlファイルの読み込み(28行目)

3.「sample.xlsx」のファイルデータ全体の参照(30行目)

図3 編集前のデータ 図3 編集前のデータ

4.行データの挿入(31行目)

図4 2行目に新しい行を挿入 図4 2行目に新しい行を挿入

5.行データの一部更新(32行目)

図5 3行目のデータを更新 図5 3行目のデータを更新

6.「sample.xlsx」の4行目データの参照(33行目)

7.行データの削除(34行目)

図6 4行目のデータを削除 図6 4行目のデータを削除

8.行データの挿入(35行目)

図7 4行目に新しい行を追加 図7 4行目に新しい行を追加

9.更新されたsheet1.xmlの生成(38行目)

10.「sample.xlsx」の生成(39行目)

 行データを参照するselectDataや行データを追加するinsertDataなど各関数について、順に説明します。

行データの参照

74 void selectData(int rowNum){
75     try {
76         Element root = document.getDocumentElement();

           /* row要素のリスト */
77         NodeList list = root.getElementsByTagName("row");
78         Element element = (Element)list.item(rowNum - 1);
79
           /* テキスト指定 */
80         NodeList textList = element.getElementsByTagName("t");
81         Element textElement = (Element)textList.item(0);

           /* A列 */
82         String a = textElement.getFirstChild().getNodeValue();
83
           /* 数値指定 */
84         NodeList numList = element.getElementsByTagName("v");
85         Element numElement = (Element)numList.item(0);

           /* B列 */
86         String b = numElement.getFirstChild().getNodeValue();              
87
88         numElement = (Element)numList.item(1);

           /* C列 */
89         String c = numElement.getFirstChild().getNodeValue();
90
91         System.out.println( rowNum+"行目: "+a+", "+b+","+c);
92     } catch (Exception e) {
93         e.printStackTrace();
94     }
95 }

 selectDataの引数に参照したい行番号を設定します。77行目でrow要素、すなわち行のリストを取得し、78行目で行リストの中から参照したい行のデータを取得します。80行目でt要素を指定してA列のテキスト、84行目でv要素を指定してB列とC列の数値を取り出します。

行データの追加

    /* 指定行に行挿入 */
109 void insertData(int rowNum, String a, int b, int c){
110     try {
111         Element root = document.getDocumentElement();
112         NodeList list = root.getElementsByTagName("row");
113         Node newRow = createRow(rowNum, a, b, c);

114         if (rowNum > list.getLength()){
115             list.item(0).getParentNode().appendChild(newRow);
116         }else {
117             list.item(0).getParentNode().insertBefore(newRow,
                    list.item(rowNum-1));
118         }
            /* 行番号の修正 */
119         for (int i=rowNum+1; i <= list.getLength(); i++) {
120             setRowAttribute(i, (Element)list.item(i-1));
121         }
122     } catch (Exception e) {
123         e.printStackTrace();
124     }
125 }

 insertDataの引数に挿入したい行番号、A列のテキスト、B列の数値、C列の数値を順に設定します。113行目で新しい行を作成し、114〜118行目で作成した行を指定行番号に追加します。119〜121行目で、追加した行の後ろの行番号が1つずつずれているので修正します。

 なお、97〜107行目の行番号指定なしのinsertDataは複数ある最後の行の次に新しい行を追加します。

行データの一部更新

127 void updateData(int rowNum, String a, int b, int c){
128     try {
129         Element root=document.getDocumentElement();
130         NodeList list = root.getElementsByTagName("row");
131         Node oldRow = list.item(rowNum - 1);
132         Node newRow = createRow(rowNum, a, b, c);
133         oldRow.getParentNode().replaceChild(newRow, oldRow);
134     } catch (Exception e) {
135         e.printStackTrace();
136     }
137 }

 updateDataの引数に更新したい行番号、A列のテキスト、B列の数値、C列の数値を順に設定します。132行目で新しい行を作成し、133行目で古い行を新しい行に更新します。

行データの削除

139 void deleteData(int rowNum){
140     try {
141         Element root=document.getDocumentElement();
142         NodeList list = root.getElementsByTagName("row");
143         list.item(0).getParentNode().removeChild(
                list.item(rowNum - 1));
144         for (int i=rowNum; i <= list.getLength() ; i++) {
145             setRowAttribute(i, (Element)list.item(i-1));
146         }
147     } catch (Exception e) {
148         e.printStackTrace();
149     }
150 }

 deleteDataの引数に削除したい行番号を設定します。143行目で指定行を削除し、144?146行目で、削除した行の後ろの行番号が1つずつずれているので修正します。

編集後のサンプルExcelファイル

 行データについて、追加、一部更新、削除が反映されたsheet1.xmlファイルを生成後、[Content_Types].xmlやworkbook.xmlなどのファイルとともにsheet1.xmlファイルをZIP圧縮すると、次のようなExcelファイルが作成されます。

図8 編集後のサンプルExcelファイル 図8 編集後のサンプルExcelファイル

標準APIでもいいが、Office操作のライブラリもある

 以上で、Javaを使ってExcelデータを操作する方法についての紹介を終わりますが、いかがでしたでしょうか?

 JavaでのOfficeデータ操作といえば、いままでのMicrosoft Officeがバイナリファイルだったこともあり(前回の「いまさら聞けないOfficeファイルフォーマット」参照)、これまではオープンソースフレームワークの「Apache POI 」(以下、POI)などに頼ることが多かったと思います。しかし、今後はJava標準APIで備わっているDOMやSAXでも操作できるようになり、技術者がいままで培ったXML操作のノウハウを生かしやすいと思います。

 もちろん、XML操作のノウハウがない技術者でも、「Open XML4J」というJavaのOpen XML操作用オープンソースライブラリが開発中のようなので、こちらを活用するのも1つの方法だと思います(2008年8月現在ベータ版のようですが)。

 また、マイクロソフトとしても、Apache Software Foundationの主要スポンサーになったことで、Officeのオープン化とともにますますオープンソース戦略を進めています。POIを含むいくつかのプロジェクトにも技術協力し、POIプロジェクトはOpen XMLのサポートもしていく予定のようです(参考:Microsoftのオープンソース計画)。

 Open XMLは今後、業務システム開発において重要な位置を占めることが予想されるので、知っておいて損はないと思います。本特集が、Office Open XMLファイルフォーマットを理解する手助けになれば幸いです。

著者プロフィール

Girier 陽子(ジリエ ヨウコ)

Office Open XML標準化作業に東芝のメンバーとして参加し、標準化組織Ecma nternationalの技術委員会「TC45」で活動。共著に「入門Office Open XML」(ソフトバンククリエイティブ)。


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。