ODSフォーマットについて、少しずつ調べていこうと思っている。
とりあえず、下記のサイト(python)を参考にしてrubyjavaでも同じように扱えないか、考えてみようと思う。

http://giraffe.topaz.ne.jp/report/
一応、改ページで印刷できることとテンプレートを他の事務社員に作ってもらうことなどを考えれば、簡易的な印刷には良いアイデアかもしれない。

jsonが取り込めるようにしたり、EXCEL側でエラーが出ないように調整できれば使いやすくなると思うがどうだろう。

とりあえず、文字コードutf-8にしてpython3で動くようにした。

# coding:utf-8

from zipfile import ZipFile, ZIP_DEFLATED
from xml.dom.minidom import parseString

# ノード内のテキストだけ再帰的に結合して取り出す
def get_text(n):
if n.nodeName == '#text':
return n.nodeValue
elif n.hasChildNodes():
return "".join([get_text(i) for i in n.childNodes])
else:
return ""

#再帰的にテキストノードをフォーマット
def dom_format(n, data):
for i in n.childNodes:
if i.nodeName == '#text':
i.nodeValue = i.nodeValue.format(**data)
else:
if i.hasChildNodes():
dom_format(i, data)

# OpenDocumentスプレッドシートをテンプレートとして使うクラス
class ODSpreadsheetTemplate(object):

def __init__(self, templatefile):
self.templatefile = templatefile
#テンプレファイルから、content.xmlをパースしておく
z = ZipFile(self.templatefile)
a = z.open('content.xml').read()
z.close()
self.domdata = parseString(a)
#最初のシートだけがテンプレ扱いの範囲
self.table = self.domdata.getElementsByTagName("table:table")[0]
self.extract_template()

#最初のセルの中身を区分記号とみなしながら、元ドキュメントから切り離す
def extract_template(self):
n = self.table
self.template = {}
for i in n.getElementsByTagName("table:table-row"):
c = i.getElementsByTagName("table:table-cell")
if len(c) > 0:
lbl = get_text(c[0])
if lbl != "":
self.template.setdefault(lbl, [])
self.template[lbl].append(i)
i.parentNode.removeChild(i)

#区分記号に合致するレポート帯を追加
def add_band(self, band, data):
for i in self.template[band]:
i2 = i.cloneNode(True)
dom_format(i2, data)
self.table.appendChild(i2)

#元zipの全構成ファイルをコピーする。content.xmlだけは細工する
def save(self, outfile):
z = ZipFile(self.templatefile)
z2 = ZipFile(outfile, "w", compression=ZIP_DEFLATED)
for i in z.infolist():
if i.filename == 'content.xml':
z2.writestr(i.filename, self.domdata.toxml().encode('utf-8'))
else:
z2.writestr(i.filename, z.open(i.filename).read())


#def main():
# t = ODSpreadsheetTemplate("template.ods")
# t.save("report.ods")

#def main():
# t = ODSpreadsheetTemplate("template.ods")
# t.add_band('h', {})
# t.add_band('h2', {'area': u'東海地方'})
# t.add_band('d', {'ken': u'愛知県', 'bird': u'コノハズク'})
# t.add_band('d', {'ken': u'三重県', 'bird': u'シロチドリ'})
# t.add_band('d', {'ken': u'岐阜県', 'bird': u'ライチョウ'})
# t.save("report.ods")


def main():
import io
brds = []
# データ読んで、並べ替え
for line in io.open('birds.txt', encoding='utf-8'):
brds.append(line[:-1].split("\t"))
#brds.sort(lambda a,b: cmp(a[0], b[0])) # python2
brds.sort(key=lambda a: a[0])
t = ODSpreadsheetTemplate("template.ods")
bf = ''
for i in brds:
#キーブレイク
if i[0] != bf:
if bf != '':
# 改ページ
t.add_band('break', {})
t.add_band('h', {'area':i[0]})
t.add_band('h2', {'area':i[0]})
bf = i[0]
t.add_band('d', {'ken':i[1], 'bird':i[2] })
t.save("report.ods")

main()