Skip to content

Commit

Permalink
Merge pull request #6 from stewartwebb/master
Browse files Browse the repository at this point in the history
Added ability to search and replace for links
  • Loading branch information
nguyenthenguyen authored Oct 5, 2017
2 parents 45fb29a + e1e7f64 commit 8b96657
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 3 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## Simple Google Go (golang) library for replace text in microsoft word (.docx) file

The following constitutes the bare minimum required to replace text in DOCX document.
``` go
``` go

import (
"github.com/nguyenthenguyen/docx"
Expand All @@ -16,6 +16,7 @@ func main() {
// Replace like https://golang.org/pkg/strings/#Replace
docx1.Replace("old_1_1", "new_1_1", -1)
docx1.Replace("old_1_2", "new_1_2", -1)
docx1.ReplaceLink("http://example.com/", "https://github.com/nguyenthenguyen/docx")
docx1.ReplaceHeader("out with the old", "in with the new")
docx1.ReplaceFooter("Change This Footer", "new footer")
docx1.WriteToFile("./new_result_1.docx")
Expand All @@ -28,4 +29,4 @@ func main() {
r.Close()
}

```
```
Binary file modified TestDocument.docx
Binary file not shown.
54 changes: 53 additions & 1 deletion docx.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
type ReplaceDocx struct {
zipReader *zip.ReadCloser
content string
links string
headers map[string]string
footers map[string]string
}
Expand All @@ -23,6 +24,7 @@ func (r *ReplaceDocx) Editable() *Docx {
return &Docx{
files: r.zipReader.File,
content: r.content,
links: r.links,
headers: r.headers,
footers: r.footers,
}
Expand All @@ -35,6 +37,7 @@ func (r *ReplaceDocx) Close() error {
type Docx struct {
files []*zip.File
content string
links string
headers map[string]string
footers map[string]string
}
Expand All @@ -53,6 +56,20 @@ func (d *Docx) Replace(oldString string, newString string, num int) (err error)
return nil
}

func (d *Docx) ReplaceLink(oldString string, newString string, num int) (err error) {
oldString, err = encode(oldString)
if err != nil {
return err
}
newString, err = encode(newString)
if err != nil {
return err
}
d.links = strings.Replace(d.links, oldString, newString, num)

return nil
}

func (d *Docx) ReplaceHeader(oldString string, newString string) (err error) {
return replaceHeaderFooter(d.headers, oldString, newString)
}
Expand Down Expand Up @@ -88,6 +105,8 @@ func (d *Docx) Write(ioWriter io.Writer) (err error) {
}
if file.Name == "word/document.xml" {
writer.Write([]byte(d.content))
} else if file.Name == "word/_rels/document.xml.rels" {
writer.Write([]byte(d.links))
} else if strings.Contains(file.Name, "header") && d.headers[file.Name] != "" {
writer.Write([]byte(d.headers[file.Name]))
} else if strings.Contains(file.Name, "footer") && d.footers[file.Name] != "" {
Expand Down Expand Up @@ -127,8 +146,13 @@ func ReadDocxFile(path string) (*ReplaceDocx, error) {
return nil, err
}

links, err := readLinks(reader.File)
if err != nil {
return nil, err
}

headers, footers, _ := readHeaderFooter(reader.File)
return &ReplaceDocx{zipReader: reader, content: content, headers: headers, footers: footers}, nil
return &ReplaceDocx{zipReader: reader, content: content, links: links, headers: headers, footers: footers}, nil
}

func readHeaderFooter(files []*zip.File) (headerText map[string]string, footerText map[string]string, err error) {
Expand Down Expand Up @@ -188,6 +212,22 @@ func readText(files []*zip.File) (text string, err error) {
return
}

func readLinks(files []*zip.File) (text string, err error) {
var documentFile *zip.File
documentFile, err = retrieveLinkDoc(files)
if err != nil {
return text, err
}
var documentReader io.ReadCloser
documentReader, err = documentFile.Open()
if err != nil {
return text, err
}

text, err = wordDocToString(documentReader)
return
}

func wordDocToString(reader io.Reader) (string, error) {
b, err := ioutil.ReadAll(reader)
if err != nil {
Expand All @@ -208,6 +248,18 @@ func retrieveWordDoc(files []*zip.File) (file *zip.File, err error) {
return
}

func retrieveLinkDoc(files []*zip.File) (file *zip.File, err error) {
for _, f := range files {
if f.Name == "word/_rels/document.xml.rels" {
file = f
}
}
if file == nil {
err = errors.New("document.xml.rels file not found")
}
return
}

func retrieveHeaderFooterDoc(files []*zip.File) (headers []*zip.File, footers []*zip.File, err error) {
for _, f := range files {

Expand Down
17 changes: 17 additions & 0 deletions docx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ func TestReplace(t *testing.T) {
}

}

func TestReplaceLink(t *testing.T) {
d := loadFile(testFile)
d.ReplaceLink("http://example.com/", "https://github.com/nguyenthenguyen/docx", -1)
d.WriteToFile(testFileResult)

d = loadFile(testFileResult)

if strings.Contains(d.links, "http://example.com") {
t.Error("Missing 'http://example.com', got ", d.links)
}

if !strings.Contains(d.links, "https://github.com/nguyenthenguyen/docx") {
t.Error("Expected 'word', got ", d.links)
}
}

func TestReplaceHeader(t *testing.T) {
d := loadFile(testFile)
d.ReplaceHeader("This is a header.", "newHeader")
Expand Down

0 comments on commit 8b96657

Please sign in to comment.