/
zip.go
90 lines (75 loc) · 1.66 KB
/
zip.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
package main
import (
"archive/zip"
"io/ioutil"
"os"
"path/filepath"
)
// File stores information about a file inside a docx
type File struct {
Name string
Contents []byte
}
// Docx stores the contents of a docx file
type Docx struct {
Name string
Files []File
WordXML string
Writer *zip.Writer
}
//LoadDocx extracts a docx into memory and allows to process the WordXML
func LoadDocx(source string) (Docx, error) {
Trace.Printf("Loading %s\n", source)
var docx Docx
reader, err := zip.OpenReader(source)
if err != nil {
return docx, err
}
docx.Name = filepath.Base(source)
docx.WordXML = "This should not be here."
for _, file := range reader.File {
var f File
f.Name = file.Name
fileReader, err := file.Open()
if err != nil {
return docx, err
}
defer fileReader.Close()
//bytes := make([]byte, file.UncompressedSize64)
bytes, err := ioutil.ReadAll(fileReader)
if err != nil {
return docx, err
}
f.Contents = bytes
if f.Name == "word/document.xml" {
docx.WordXML = string(f.Contents)
} else {
docx.Files = append(docx.Files, f)
}
}
defer reader.Close()
return docx, nil
}
// WriteToFile creates a zip with all its contents
func (d *Docx) WriteToFile(target string) error {
docxFile, err := os.Create(target)
if err != nil {
return err
}
defer docxFile.Close()
d.Writer = zip.NewWriter(docxFile)
defer d.Writer.Close()
for _, f := range d.Files {
zippedFile, err := d.Writer.Create(f.Name)
if err != nil {
return err
}
zippedFile.Write(f.Contents)
}
zippedFile, err := d.Writer.Create("word/document.xml")
if err != nil {
return err
}
zippedFile.Write([]byte(d.WordXML))
return nil
}