68 lines
1.8 KiB
Ruby
68 lines
1.8 KiB
Ruby
require 'zip'
|
|
require 'nokogiri'
|
|
require 'combine_pdf'
|
|
|
|
module Letters
|
|
def self.apply_template(io, params)
|
|
Zip::OutputStream.write_buffer do |out|
|
|
Zip::File.open(io) do |zip|
|
|
zip.each do |entry|
|
|
out.put_next_entry(entry.name)
|
|
if entry.name == "content.xml"
|
|
out.write apply_template_xml(entry.get_input_stream.read, params)
|
|
elsif !entry.directory?
|
|
out.write entry.get_input_stream.read
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.apply_template_xml(xml, params)
|
|
doc = Nokogiri::XML(xml)
|
|
|
|
doc.xpath("//*[contains(text(), 'DISPLAY_NAME')]").each do |node|
|
|
node.content = node.content.gsub("DISPLAY_NAME", params["DISPLAY_NAME"])
|
|
end
|
|
|
|
address_lines = params['ADDRESS'].split("\n")
|
|
doc.xpath("//*[contains(text(), 'ADDRESS')]").each do |node|
|
|
newnodes = [node] + address_lines[1..].map do |line|
|
|
node.clone.tap do |c|
|
|
c.content = c.content.gsub("ADDRESS", line)
|
|
end
|
|
end
|
|
node.content = node.content.gsub("ADDRESS", address_lines.first)
|
|
|
|
newnodes.each_cons(2) do |p, n|
|
|
p.add_next_sibling(n)
|
|
end
|
|
end
|
|
|
|
doc.to_xml(save_with: 0)
|
|
end
|
|
|
|
def self.generate(template, members)
|
|
Dir.mktmpdir do |directory|
|
|
members.each do |member|
|
|
odt = apply_template(template, {
|
|
"DISPLAY_NAME" => member.display_name,
|
|
"ADDRESS" => member.address,
|
|
})
|
|
|
|
File.open("#{directory}/#{member.number}.odt", "wb") { |out| out.write(odt.string) }
|
|
end
|
|
|
|
`libreoffice --convert-to pdf --outdir #{directory} #{directory}/*.odt`
|
|
|
|
pdf = CombinePDF.new
|
|
|
|
Dir["#{directory}/*.pdf"].each do |file|
|
|
pdf << CombinePDF.load(file)
|
|
end
|
|
|
|
pdf.to_pdf
|
|
end
|
|
end
|
|
end
|