Редактировать docx используя nokogiri и rubyzip - PullRequest
5 голосов
/ 31 января 2012

Здесь я использую rubyzip и nokogiri для изменения файла .docx.

RubyZip -> Unzip .docx file
Nokogiri -> Parse and change in content of the body of word/document.xml

Как я написал пример кода чуть ниже, но код изменил файл, но другие файлы были нарушены. Другими словами, обновленный файл не открывается с ошибкой текстового процессора. Как я могу решить эту проблему?

require 'zip/zipfilesystem'
require 'nokogiri'
zip = Zip::ZipFile.open("SecurityForms.docx")
doc = zip.find_entry("word/document.xml")
xml = Nokogiri::XML.parse(doc.get_input_stream)
wt = xml.root.xpath("//w:t", {"w" => "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}).first
wt.content = "FinalStatement"
zip.get_output_stream("word/document.xml") {|f| f << xml.to_s}
zip.close

Ответы [ 2 ]

2 голосов
/ 01 февраля 2014

Согласно официальной документации Github , вам следует Use write_buffer instead open. Также по ссылке приведен пример кода.

1 голос
/ 09 февраля 2013

Ниже приведен код, который редактирует содержимое файла шаблона .docx. Сначала создайте новую копию вашего шаблона. Помните, что вы создадите этот файл шаблона и сохраните этот файл в той же папке, где вы создаете свой класс ruby. Как вы создадите My_Class.rb и скопируйте в него следующий код. Это отлично работает для моего случая. Помните, что вам нужно установить гем rubyzip и nokogiri в набор гемов. (Google их установить). Спасибо

require 'rubygems'
require 'zip/zipfilesystem'
require 'nokogiri'
class Edit_docx
def initialize
coupling =  [('a'..'z'),('A'..'Z')].map{|i| i.to_a}.flatten
secure_string  =  (0...50).map{ coupling[rand(coupling.length)] }.join
FileUtils.cp 'template.docx', "#{secure_string}.docx"
zip = Zip::ZipFile.open("#{secure_string}.docx")
doc = zip.find_entry("word/document.xml")
xml = Nokogiri::XML.parse(doc.get_input_stream)
wt = xml.root.xpath("//w:t", {"w"=>"http://schemas.openxmlformats.org/wordprocessingml/2006/main"})
#puts wt
wt.each_with_index do |tag,i|
tag.content = i.to_s + ""
end
zip.get_output_stream("word/document.xml") {|f| f << xml.to_s}
zip.close
puts secure_string
#FileUtils.rm("#{secure_string}.docx")
end
N.new
end
...