1
1
# encoding: UTF-8
2
2
require "htmltoword/version"
3
+ require "htmltoword/htmltoword_helper"
3
4
require "action_controller"
4
5
require "action_view"
5
6
require "nokogiri"
@@ -9,21 +10,57 @@ module Htmltoword
9
10
def self . root
10
11
File . expand_path '../..' , __FILE__
11
12
end
13
+ def self . templates_path
14
+ File . join root , "templates"
15
+ end
12
16
13
17
class Document
18
+
14
19
DOC_XML_FILE = "word/document.xml"
15
20
BASIC_PATH = ::Htmltoword . root
16
- TEMPLATES_PATH = File . join BASIC_PATH , "templates "
17
- REL_PATH = "/tmp"
21
+ SAVING_REL_PATH = "public/tmp "
22
+ BASIC_REL_URL = "/tmp"
18
23
FILE_EXTENSION = ".docx"
19
24
XSLT_TEMPLATE = File . join ( BASIC_PATH , 'xslt' , 'html_to_wordml.xslt' )
20
25
21
- def initialize ( path )
26
+ class << self
27
+ include HtmltowordHelper
28
+
29
+ def create content , file_name
30
+ word_file = new ( template_file , file_name )
31
+ word_file . replace_file content
32
+ word_file . save
33
+ word_file . rel_url
34
+ end
35
+
36
+ def create_with_content template , file_name , content , set = nil
37
+ word_file = new ( template_file ( "#{ template } #{ FILE_EXTENSION } " ) , file_name )
38
+ content = replace_values ( content , set ) if set
39
+ word_file . replace_file content
40
+ word_file . save
41
+ word_file . rel_url
42
+ end
43
+ end
44
+
45
+ def initialize ( template_path , file_name )
46
+ @file_name = "#{ file_name } #{ FILE_EXTENSION } "
22
47
@replaceable_files = { }
23
- @template_zip = Zip ::ZipFile . open ( path )
48
+ @template_zip = Zip ::ZipFile . open ( template_path )
49
+ end
50
+
51
+ def file_name
52
+ @file_name
24
53
end
25
54
26
- def save_to ( path )
55
+ #
56
+ # It creates missing folders if needed, creates a new zip/word file on the
57
+ # specified location, copies all the files from the template word document
58
+ # and replace the content of the ones to be replaced.
59
+ #
60
+ # path: Could be an absolute or relative path, by default it uses a
61
+ # relative path defined on <code>rel_path</code>
62
+ #
63
+ def save ( path = rel_path )
27
64
FileUtils . mkdir_p File . dirname ( path )
28
65
Zip ::ZipFile . open ( path , Zip ::ZipFile ::CREATE ) do |out |
29
66
@template_zip . each do |entry |
@@ -39,67 +76,20 @@ def save_to(path)
39
76
@template_zip . close
40
77
end
41
78
42
- def replace_body content
43
- xml = @template_zip . read ( DOC_XML_FILE ) . force_encoding ( "UTF-8" )
44
- content . gsub! ( "\n " , "" )
45
- xml . gsub! ( /<w:body>.*<\/ w:body>/ , "<w:body>#{ content . gsub ( "\n " , "" ) } </w:body>" )
46
- @replaceable_files [ DOC_XML_FILE ] = xml
47
- end
48
-
49
79
def replace_file html , file_name = DOC_XML_FILE
50
80
source = Nokogiri ::HTML ( html . gsub ( />\s +</ , "><" ) )
51
81
xslt = Nokogiri ::XSLT ( File . read ( XSLT_TEMPLATE ) )
52
82
source = xslt . transform ( source ) unless ( source /"/html" ) . blank?
53
83
@replaceable_files [ file_name ] = source . to_s
54
84
end
55
85
56
- def self . template_file template
57
- default_path = File . join ( TEMPLATES_PATH , "template#{ FILE_EXTENSION } " )
58
- template_path = File . join ( TEMPLATES_PATH , "#{ template } #{ FILE_EXTENSION } " )
59
- File . exist? ( template_path ) ? template_path : default_path
60
- end
61
-
62
- def self . create content , file_name
63
- word_file = new ( template_file ( "overview" ) )
64
- word_file . replace_file content
65
- relative_path = File . join REL_PATH , "#{ file_name } #{ FILE_EXTENSION } "
66
- word_file . save_to File . join ( "public" , relative_path )
67
- relative_path
86
+ def rel_path
87
+ File . join ( SAVING_REL_PATH , file_name )
68
88
end
69
89
70
- def self . create_with_content template , file_name , content , set = nil
71
- word_file = new ( template_file ( template ) )
72
- content = replace_values ( content , set ) if set
73
- word_file . replace_file content
74
- relative_path = File . join REL_PATH , "#{ file_name } #{ FILE_EXTENSION } "
75
- word_file . save_to File . join ( "public" , relative_path )
76
- relative_path
90
+ def rel_url
91
+ File . join ( BASIC_REL_URL , file_name )
77
92
end
78
93
79
- private
80
- def self . replace_values content , set
81
- doc = Nokogiri ::HTML ( content )
82
- set . each_pair do |key , value |
83
- fields = ( doc /"//span[@data-id='#{ key } ']" )
84
- fields . each do |f |
85
- date_format = f . attr ( "date-format" ) || "long"
86
- data_transform = f . attr ( "data-transform" )
87
- if value . is_a? Hash
88
- view = ActionView ::Base . new ( ActionController ::Base . view_paths , { } )
89
- final_value = view . render "partials/answer_table" , answer : value
90
- fragment = doc . root . parse ( final_value ) . first
91
- new_node = doc . root . add_child ( fragment )
92
- f . parent . replace new_node
93
- elsif value . is_a? Time
94
- f . content = I18n . l ( value . to_date , format : date_format . to_sym )
95
- elsif data_transform == "capitalized"
96
- f . content = value . mb_chars . capitalize rescue value
97
- else
98
- f . content = value
99
- end
100
- end
101
- end
102
- doc . to_s
103
- end
104
94
end
105
95
end
0 commit comments