class MyDocx
クラス/MyDocx¶ ↑
docxを扱うクラスです 主な機能は次のとおりです * テンプレートファイルの場所を指定してインスタンス化します * keysメソッドでテンプレートファイルに含まれる変数(以下、テンプレートファイルで使う変数を単に変数といいます)を取得します * setメソッドで変数に値を代入することができます * generateメソッドでdocxファイルを生成します
Constants
- VAR_REGEX
変数を定義する正規表現¶ ↑
変数の定義¶ ↑
* @@で始まり、@@で終わる * 半角アルファベットの大文字・小文字またはアンダーバーで始まる * 2文字目以降は半角アルファベットの大文字・小文字アンダーバーのほかに数字とピリオドを使うことができる * 最初のピリオドから次のピリオドないし最後の@@までの文字列をプロパティという 例:: @@hello.text@@ - .checkboxプロパティ 値をStringの"1"に指定すると☑に置換えます。それ以外の値は☐に置換えます - .textプロパティ 改行も含めて再現します
Public Class Methods
new(path_to_template)
click to toggle source
initialize¶ ↑
インスタンスの初期化 Param:: path_to_templateはテンプレートファイルの場所を指定します テンプレートファイルに半角スペースなどを含んでいると生成されたdocxにエラーが出ます
# File lib/simple_docx_generator/mydocx.rb, line 30 def initialize(path_to_template) @keys_index = {} @filename = File.basename(path_to_template) @dir = File.dirname(path_to_template) set_document_xml(path_to_template) set_keys_index end
Public Instance Methods
all_text()
click to toggle source
document_xml()
click to toggle source
# File lib/simple_docx_generator/mydocx.rb, line 114 def document_xml @document_xml.to_xml end
generate(filename = 'output_' + @filename)
click to toggle source
generate¶ ↑
@document_xmlを使ってdocxファイルを生成します docxファイルはテンプレートファイルと同じディレクトリに生成されます もし同じファイル名のファイルが存在していた場合はそのファイルを上書きします Param:: filenameにdocx拡張子をつけた名前がファイル名となります もしfilenameを指定しない場合はoutput_元のファイル名.docxというファイルになります Return: パス付きのfilenameを値として返します
# File lib/simple_docx_generator/mydocx.rb, line 96 def generate(filename = 'output_' + @filename) File.delete(filename) if File.exist?(filename) buffer = Zip::OutputStream.write_buffer(::StringIO.new('')) do |out| Zip::InputStream.open(File.join(@dir, @filename)) do |input| while (entry = input.get_next_entry) out.put_next_entry(entry.name) if entry.name == 'word/document.xml' out.write @document_xml.to_xml else out.write input.read end end end end File.open(File.join(@dir, filename), 'wb') {|f| f.write(buffer.string)} File.join @dir, filename end
keys()
click to toggle source
keys_index()
click to toggle source
keys_index
¶ ↑
変数と変数が含まれている場所です Return:: 形式は変数をkey、対応する場所のArray(同じ変数がテンプレートファイル内に複数存在する可能性があります)をvalueとしたハッシュ形式です。デバッグ用。
# File lib/simple_docx_generator/mydocx.rb, line 64 def keys_index @keys_index end
set(key, value = '')
click to toggle source
set¶ ↑
変数に値を代入します Params:: key, valueともにString valueを指定しない場合は''になります Return:: setに成功したらtrue、失敗したらfalseが返ります 典型的にはkeyが存在しない場合を想定しています
# File lib/simple_docx_generator/mydocx.rb, line 43 def set(key, value = '') value = set_checkbox_value(key, value) if key.gsub(/@@/, '').split('.')[1] == 'text' replace_br(key, value) else replace(key, value) end end
to_html(class_name='')
click to toggle source
to_html
¶ ↑
ydocxというパーサーを介して<div>タグで囲んだhtmlを返します オプションで<div>タグのclass名を指定できます
# File lib/simple_docx_generator/mydocx.rb, line 79 def to_html(class_name='') ydocx = YDocx::Document.open File.join(@dir, @filename) html = Nokogiri::HTML ydocx.to_html nodes = html.xpath("//body").children myhtml = Nokogiri::HTML::DocumentFragment.parse "<div></div>" myhtml.child['class'] = class_name unless class_name.empty? myhtml.child << nodes myhtml.to_s end
update_xml(xml_text)
click to toggle source
# File lib/simple_docx_generator/mydocx.rb, line 118 def update_xml xml_text buffer = Zip::OutputStream.write_buffer(::StringIO.new('')) do |out| Zip::InputStream.open(File.join(@dir, @filename)) do |input| while (entry = input.get_next_entry) out.put_next_entry(entry.name) if entry.name == 'word/document.xml' out.write xml_text else out.write input.read end end end end File.open(File.join(@dir, @filename), 'wb') {|f| f.write(buffer.string)} initialize File.join(@dir, @filename) end
Private Instance Methods
replace(key, value)
click to toggle source
# File lib/simple_docx_generator/mydocx.rb, line 165 def replace(key, value) index = @keys_index[key] unless index == nil index.each do |num| text = @document_xml.xpath("//w:t")[num].content text.gsub!(key, value) @document_xml.xpath("//w:t")[num].content = text end true else false end end
replace_br(key, value)
click to toggle source
# File lib/simple_docx_generator/mydocx.rb, line 179 def replace_br(key, value) index = @keys_index[key] unless index == nil index.each do |num| index_node = @document_xml.xpath("//w:t")[num].parent index_p_node = index_node.parent @document_xml.xpath("//w:t")[num].remove frag = Nokogiri::XML::DocumentFragment.new @document_xml value.split("\n").each do |t| run_node = index_node.dup p_node = index_p_node.dup node = Nokogiri::XML::Node.new "t", @document_xml node['prefix'] = "w" node.content = t run_node << node p_node << run_node frag << p_node end index_p_node.add_next_sibling frag index_p_node.remove end set_keys_index true else false end end
set_checkbox_value(key, value)
click to toggle source
# File lib/simple_docx_generator/mydocx.rb, line 158 def set_checkbox_value(key, value) if key.gsub(/@@/, '').split('.')[1] == 'checkbox' value = (value == "1") ? "☑" : "☐" end value end
set_document_xml(path_to_template)
click to toggle source
# File lib/simple_docx_generator/mydocx.rb, line 136 def set_document_xml(path_to_template) Zip::File.open(path_to_template) do |zip_files| document_file = zip_files.find_entry('word/document.xml') @document_xml = Nokogiri::XML document_file.get_input_stream.read end end
set_keys_index()
click to toggle source
# File lib/simple_docx_generator/mydocx.rb, line 143 def set_keys_index i = 0 @document_xml.xpath("//w:t").each do |t_node| text = t_node.content if VAR_REGEX =~ text text.scan(VAR_REGEX).each do |t| @keys_index[t] ||= [] @keys_index[t] << i end end # t_node.set_attribute("text_no" , i.to_s) i += 1 end end