5

Here, I'm using a rubyzip and nokogiri to modify a .docx file.

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

As I wrote the sample code just below but code modify the file but others file were disturbed. In other words, updated file is not opening showing error the word processor is crashed. How can I resolve this issue ?

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
halfer
  • 19,824
  • 17
  • 99
  • 186
Rubyist
  • 6,486
  • 10
  • 51
  • 86

2 Answers2

2

According to the official Github documentation, you should Use write_buffer instead open. There's also a code example at the link.

Waynn Lue
  • 11,344
  • 8
  • 51
  • 76
  • 1
    Their paragraph about docx is a bit confusing. I understand that `DOCUMENT_FILE_PATH` and `new_path` refer to the original and new docx filepaths, but what is `RELS_FILE_PATH` ? – Cyril Duchon-Doris Sep 07 '14 at 17:51
  • My bets guess is that `DOCUMENT_FILE_PATH` is the word document xml itself `word/document.xml` and `RELS_FILE_PATH` is `word/_rels/document.xml.rels`. However the example on github docs didn't work for me (produced corrupted .docx files) until I changed `File.open(new_path, "w") {|f| f.write(buffer.string) }` to `File.open(new_path, "wb") {|f| f.write(buffer.string) }`, note the binary mode. – Sash Nov 28 '14 at 22:54
1

Following is the code that edit the content of a .docx template file.It first creae a new copy of your template.docx remember u will create this template file and keep this file in the same folder where you create your ruby class like you will create My_Class.rb and copy following code in it.It works perfectly for my case. Remember you need to install rubyzip and nokogiri gem in a gemset.(Google them to install).Thanks

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
Muhammad Ateq Ejaz
  • 1,845
  • 20
  • 22