国際化プログラミングをする時にXXXX.propertiesファイルを作成するけれども、
設計書(Excel)から設定ファイルにいちいち直すのではなくExcelから直接読み取れないかなということで調べてみました。
国際化対応をする場合はResourceBundleクラスを使用するのだけれども、
このクラスとResourceBundle.Controlクラスを継承することで、Excelファイルを読み込めるようになります。
概要はJavaDocに書いてあるとおりなので幾つかピンポイントで。
http://java.sun.com/javase/ja/6/docs/ja/api/java/util/ResourceBundle.Control.html
ResourceBundle.Control#getFormats(String baseName)ではxlsを返すようにします。
@Override public List<String> getFormats(String baseName) { if (baseName == null) throw new NullPointerException(); return Arrays.asList("xls"); }
ResourceBundle.Control#newBundle()内ではJavaDocのサンプル通りに実装したあとに、
XmlResourceBundleの代わりに以下のExcelResourceBundleを返すようにします。
private static class ExcelResourceBundle extends ResourceBundle { private Properties props; ExcelResourceBundle(InputStream stream) throws IOException { props = new Properties(); Workbook book = new HSSFWorkbook(new POIFSFileSystem(stream)); Sheet sheet = book.getSheet("messages"); for (Row row : sheet) { Cell keyCell = row.getCell(0); Cell valueCell = row.getCell(1); if (keyCell == null) { continue; } String key = keyCell.getStringCellValue(); String value = (valueCell == null) ? "" : valueCell .getStringCellValue(); if (isTitleOrEmpty(key)) { continue; } props.setProperty(key, value); } } private boolean isTitleOrEmpty(String key) { return "Key".equals(key) || key == null || key.length() == 0; } protected Object handleGetObject(String key) { return props.getProperty(key); } public Enumeration<String> getKeys() { return (Enumeration<String>) props.propertyNames(); } }
※Excelファイルのサンプルも含めてソースは下からDLしてください。
http://www1.axfc.net/uploader/Sc/so/276281.zip (eclipse+maven)
これだけで、XXXX.xls、XXXXX_ja_JP.xls、XXXXX_en.xls等をさがしに行ってくれるようです。
今回はファイル名で分けていますが、Excelファイルをひとつにして、シート名で国際化対応ということもできそうです。
Excelから直接読み込めればいいなとだけ考えてたけれども、思ったよりも便利かもしれません。