-
Notifications
You must be signed in to change notification settings - Fork 0
/
docx.go
101 lines (89 loc) · 2.33 KB
/
docx.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Package cetak helps you generate Word document (.docx) from a template.
package cetak
import (
"archive/zip"
"bytes"
"io"
"os"
"text/template"
)
// Docx is the interface used to interact with cetak's doc generator
//
// Generate generates the document using given data.
// Generate receive data which can be any type that is accepted by text/template package.
// Generate also receive destination path which is the intended path to write the result.
// You can also get the generated template and modify it accordingly using
// the provided getter and setter (Template and SetTemplate)
type Docx interface {
Generate(data interface{}, destination string) error
Template() *template.Template
SetTemplate(tpl *template.Template)
}
type docx struct {
tpl *template.Template
templatePath string
}
// New creates a new Docx object. It will return error if template file could not be opened.
func New(templatePath string) (Docx, error) {
tplString, err := getDocxContentAsString(templatePath)
if err != nil {
return nil, err
}
tpl, err := template.New("template").Parse(tplString)
if err != nil {
return nil, err
}
return &docx{
tpl: tpl,
templatePath: templatePath,
}, nil
}
// Generate generates the document content based on the template set in d object
func (d *docx) Generate(data interface{}, destination string) error {
var resultBuf bytes.Buffer
err := d.tpl.Execute(&resultBuf, data)
if err != nil {
return err
}
destFile, err := os.Create(destination)
if err != nil {
return err
}
docxWriter := zip.NewWriter(destFile)
acts := actions{
"word/document.xml": func(f *zip.File) error {
docFile, err := docxWriter.Create(f.Name)
if err != nil {
return err
}
if _, err = docFile.Write([]byte(resultBuf.String())); err != nil {
return err
}
return nil
},
}
defaultAct := func(f *zip.File) error {
docFile, err := docxWriter.Create(f.Name)
if err != nil {
return err
}
tplFileReader, err := f.Open()
if err != nil {
return err
}
if _, err = io.Copy(docFile, tplFileReader); err != nil {
return err
}
return nil
}
if err := executeOnDocx(d.templatePath, acts, defaultAct); err != nil {
return err
}
return docxWriter.Close()
}
func (d *docx) Template() *template.Template {
return d.tpl
}
func (d *docx) SetTemplate(tpl *template.Template) {
d.tpl = tpl
}