問題
- POI(3.8)をevent-apiを使ってExcelシートのセルの文字列を取得したら、後ろにゴミが付いてた。
- Apache POIを使ったExcel 2007形式のシートの取込処理を保守していた。
- ちょっと大きいExcelシートを取り込んだら、メモリー不足になっので、event-api を使って取り込むようにした。
- プログラムの動きがおかしいので、データを確認したら文字列の後ろにフリガナぽいゴミがついてた。
- 「未対策」が取れるはずなのに、「未対策ミタイサク」になってしまう。はて。
分析
- Excelファイルの拡張子をzipにして解凍。sharedString.xmlを参照してみる。
sharedString.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>未対策</t><rPh sb="13" eb="14"><t>ミ</t></rPh><rPh sb="14" eb="16"><t>タイサク</t></rPh><phoneticPr fontId="19"/></si></sst>
- **<rPh>と</rPh>**の中に「ミ」と「タイサク」が格納されている。
- Excelシートに入力時にふりがなが保存されているぽい。**<rPh>**は無視するようにすればいいか。
対策
- ReadOnlySharedStringsTableクラスをOverrideして**<rPh>タグ内の<t>**は取り込まないようにしました。
MyStringTable.java
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
public class MyStringsTable extends ReadOnlySharedStringsTable {
private boolean isPhonetic;
public MyStringsTable(OPCPackage pkg) throws IOException, SAXException {
super(pkg);
}
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
if ("rPh".equals(name)) {
isPhonetic = true;
}
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
super.endElement(uri, localName, name);
if ("rPh".equals(name)) {
isPhonetic = false;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (!isPhonetic) {
super.characters(ch, start, length);
}
}
}
...
- Excelのフリガナ機能って日本独自の仕様なのかね。みんな使われているんだろうか。
- 初めての投稿なのでドキドキ。もっと丁寧に書きたいけど、とりあえずこれで。
- 作成時間15分