From 2d8e70681551acbd093ac7168b0b5960fbabe494 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?=
<41315874+fumiama@users.noreply.github.com>
Date: Thu, 9 Feb 2023 14:05:31 +0800
Subject: [PATCH] feat: embed template xmls
---
.gitignore | 2 +
apidrawing.go | 7 +
apirun.go | 16 --
apitext.go | 17 ++
cmd/getstructure/main.go | 3 +-
cmd/main/main.go | 12 +-
empty_constants.go | 389 --------------------------------------
files.go | 9 +
pack.go | 40 ++--
structdoc_test.go | 26 ++-
structnodes.go | 4 +-
xml/[Content_Types].xml | 10 +
xml/_rels/.rels | 6 +
xml/docProps/app.xml | 1 +
xml/docProps/core.xml | 1 +
xml/word/styles.xml | 49 +++++
xml/word/theme/theme1.xml | 318 +++++++++++++++++++++++++++++++
17 files changed, 481 insertions(+), 429 deletions(-)
create mode 100644 apidrawing.go
create mode 100644 apitext.go
delete mode 100644 empty_constants.go
create mode 100644 files.go
create mode 100644 xml/[Content_Types].xml
create mode 100644 xml/_rels/.rels
create mode 100644 xml/docProps/app.xml
create mode 100644 xml/docProps/core.xml
create mode 100644 xml/word/styles.xml
create mode 100644 xml/word/theme/theme1.xml
diff --git a/.gitignore b/.gitignore
index 70f0a4b..196db6b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
docxlib
.vscode/
+*.docx
+/*.xml
\ No newline at end of file
diff --git a/apidrawing.go b/apidrawing.go
new file mode 100644
index 0000000..bc8d3c4
--- /dev/null
+++ b/apidrawing.go
@@ -0,0 +1,7 @@
+package docxlib
+
+// AddDrawing adds drawing to paragraph
+func (p *Paragraph) AddDrawing(pic []byte) *Run {
+ //TODO: finish add drawing
+ return nil
+}
diff --git a/apirun.go b/apirun.go
index f7af38c..32e9627 100644
--- a/apirun.go
+++ b/apirun.go
@@ -17,19 +17,3 @@ func (r *Run) Size(size int) *Run {
return r
}
-
-// AddText adds text to paragraph
-func (p *Paragraph) AddText(text string) *Run {
- t := &Text{
- Text: text,
- }
-
- run := &Run{
- Text: t,
- RunProperties: &RunProperties{},
- }
-
- p.Children = append(p.Children, ParagraphChild{Run: run})
-
- return run
-}
diff --git a/apitext.go b/apitext.go
new file mode 100644
index 0000000..c556aa6
--- /dev/null
+++ b/apitext.go
@@ -0,0 +1,17 @@
+package docxlib
+
+// AddText adds text to paragraph
+func (p *Paragraph) AddText(text string) *Run {
+ t := &Text{
+ Text: text,
+ }
+
+ run := &Run{
+ Text: t,
+ RunProperties: &RunProperties{},
+ }
+
+ p.Children = append(p.Children, ParagraphChild{Run: run})
+
+ return run
+}
diff --git a/cmd/getstructure/main.go b/cmd/getstructure/main.go
index a0c7c63..f491e1d 100644
--- a/cmd/getstructure/main.go
+++ b/cmd/getstructure/main.go
@@ -11,7 +11,7 @@ import (
var fileLocation *string
func init() {
- fileLocation = flag.String("file", "/tmp/new-file.docx", "file location")
+ fileLocation = flag.String("file", "new-file.docx", "file location")
flag.Parse()
}
@@ -21,6 +21,7 @@ func main() {
if err != nil {
panic(err)
}
+ defer readFile.Close()
fileinfo, err := readFile.Stat()
if err != nil {
panic(err)
diff --git a/cmd/main/main.go b/cmd/main/main.go
index 538e425..1c2b27a 100644
--- a/cmd/main/main.go
+++ b/cmd/main/main.go
@@ -11,7 +11,7 @@ import (
var fileLocation *string
func init() {
- fileLocation = flag.String("file", "/tmp/new-file.docx", "file location")
+ fileLocation = flag.String("file", "new-file.docx", "file location")
flag.Parse()
}
func main() {
@@ -35,8 +35,14 @@ func main() {
if err != nil {
panic(err)
}
- defer f.Close()
- w.Write(f)
+ err = w.Write(f)
+ if err != nil {
+ panic(err)
+ }
+ err = f.Close()
+ if err != nil {
+ panic(err)
+ }
fmt.Println("Document writen. \nNow trying to read it")
// Now let's try to read the file
readFile, err := os.Open(*fileLocation)
diff --git a/empty_constants.go b/empty_constants.go
deleted file mode 100644
index ec8a94e..0000000
--- a/empty_constants.go
+++ /dev/null
@@ -1,389 +0,0 @@
-package docxlib
-
-const (
- TEMP_REL = `
-
-
-
-
- `
- TEMP_DOCPROPS_APP = `Go DOCX`
- TEMP_DOCPROPS_CORE = ``
- TEMP_CONTENT = `
-
-
-
-
-
-
-
-
- `
- TEMP_WORD_STYLE = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `
- TEMP_WORD_THEME_THEME = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `
-)
diff --git a/files.go b/files.go
new file mode 100644
index 0000000..4b09dac
--- /dev/null
+++ b/files.go
@@ -0,0 +1,9 @@
+package docxlib
+
+import "embed"
+
+var (
+ //go:embed xml
+ //go:embed xml/_rels/*
+ TEMP_XML_FS embed.FS
+)
diff --git a/pack.go b/pack.go
index e48a4d6..6801db3 100644
--- a/pack.go
+++ b/pack.go
@@ -2,29 +2,37 @@ package docxlib
import (
"archive/zip"
+ "bytes"
"encoding/xml"
- "strings"
)
// This receives a zip file writer (word documents are a zip with multiple xml inside)
// and writes the relevant files. Some of them come from the empty_constants file,
// others from the actual in-memory structure
func (f *Docx) pack(zipWriter *zip.Writer) (err error) {
- files := map[string]string{}
+ fileslst := []string{
+ "_rels/.rels",
+ "docProps/app.xml",
+ "docProps/core.xml",
+ "word/theme/theme1.xml",
+ "word/styles.xml",
+ "[Content_Types].xml",
+ }
+ files := make(map[string][]byte, 64)
- files["_rels/.rels"] = TEMP_REL
- files["docProps/app.xml"] = TEMP_DOCPROPS_APP
- files["docProps/core.xml"] = TEMP_DOCPROPS_CORE
- files["word/theme/theme1.xml"] = TEMP_WORD_THEME_THEME
- files["word/styles.xml"] = TEMP_WORD_STYLE
- files["[Content_Types].xml"] = TEMP_CONTENT
+ for _, name := range fileslst {
+ files[name], err = TEMP_XML_FS.ReadFile("xml/" + name)
+ if err != nil {
+ return
+ }
+ }
files["word/_rels/document.xml.rels"], err = marshal(f.DocRelation)
if err != nil {
- return err
+ return
}
files["word/document.xml"], err = marshal(f.Document)
if err != nil {
- return err
+ return
}
for path, data := range files {
@@ -33,7 +41,7 @@ func (f *Docx) pack(zipWriter *zip.Writer) (err error) {
return err
}
- _, err = w.Write(StringToBytes(data))
+ _, err = w.Write(data)
if err != nil {
return err
}
@@ -42,13 +50,13 @@ func (f *Docx) pack(zipWriter *zip.Writer) (err error) {
return
}
-func marshal(data interface{}) (out string, err error) {
- sb := strings.Builder{}
- sb.WriteString(xml.Header)
- err = xml.NewEncoder(&sb).Encode(data)
+func marshal(data interface{}) (out []byte, err error) {
+ buf := bytes.NewBuffer(make([]byte, 0, 1024))
+ buf.WriteString(xml.Header)
+ err = xml.NewEncoder(buf).Encode(data)
if err != nil {
return
}
- out = sb.String()
+ out = buf.Bytes()
return
}
diff --git a/structdoc_test.go b/structdoc_test.go
index 3cb1e68..1d8bb4e 100644
--- a/structdoc_test.go
+++ b/structdoc_test.go
@@ -2,13 +2,14 @@ package docxlib
import (
"encoding/xml"
+ "os"
"testing"
)
const decoded_doc_1 = `testtest font sizetest colorNew style 1New style 2test font size and colorgoogle`
const decoded_doc_2 = `Table of Contents TOC \h \z \t "Heading 1,2,S6,1,S0,1,S1,1,S2,1,S3,1,S4,1,S5,1" Holy Grail [xref:bRJduW6hNR] PAGEREF _Toc420414504 \h 21.What is your name? [xref:TH7u7QDqhD] PAGEREF _Toc420414505 \h 22.What is your quest? [xref:bC62HkFATC] PAGEREF _Toc420414506 \h 23.What is your favourite colour? [xref:I3TphuHX6N] PAGEREF _Toc420414507 \h 2Holy Grail [ FORMTEXT xref:bRJduW6hNR]What is your name? [ FORMTEXT xref:TH7u7QDqhD]My name is Sir Launcelot of Camelot.What is your quest? [ FORMTEXT xref:bC62HkFATC]To seek the Holy Grail[or a grail shaped beacon]. What is your favourite colour? [ FORMTEXT xref:I3TphuHX6N]Blue.How many paragraphs here then?`
-func TestPlainStructure(t *testing.T) {
+func TestUnmarshalPlainStructure(t *testing.T) {
doc := Document{
XMLW: XMLNS_W,
XMLR: XMLNS_R,
@@ -512,7 +513,7 @@ const drawing_doc = `
`
-func TestDrawingStructure(t *testing.T) {
+func TestUnmarshalDrawingStructure(t *testing.T) {
doc := Document{
XMLW: XMLNS_W,
XMLR: XMLNS_R,
@@ -560,3 +561,24 @@ func TestDrawingStructure(t *testing.T) {
}
}
}
+
+func TestMarshalDrawingStructure(t *testing.T) {
+ w := New()
+ // add new paragraph
+ para1 := w.AddParagraph()
+ // add text
+ para1.AddText("直接粘贴 inline")
+
+ para2 := w.AddParagraph()
+ para2.AddText("test font size and color").Size(22).Color("ff0000")
+
+ nextPara := w.AddParagraph()
+ nextPara.AddLink("google", `http://google.com`)
+
+ doc, err := marshal(w.Document)
+ if err != nil {
+ t.Fatal(err)
+ }
+ os.WriteFile("test.xml", doc, 0644)
+ t.Fail()
+}
diff --git a/structnodes.go b/structnodes.go
index 4b5a19b..a284032 100644
--- a/structnodes.go
+++ b/structnodes.go
@@ -12,8 +12,8 @@ type ParagraphChild struct {
}
type Paragraph struct {
- XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main p"`
- Children []ParagraphChild
+ XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main p"`
+ Children []ParagraphChild // Children will generate an unnecessary tag ... but we have no other choice
file *Docx
}
diff --git a/xml/[Content_Types].xml b/xml/[Content_Types].xml
new file mode 100644
index 0000000..64ddaa5
--- /dev/null
+++ b/xml/[Content_Types].xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/_rels/.rels b/xml/_rels/.rels
new file mode 100644
index 0000000..f6210ee
--- /dev/null
+++ b/xml/_rels/.rels
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/docProps/app.xml b/xml/docProps/app.xml
new file mode 100644
index 0000000..ca90e47
--- /dev/null
+++ b/xml/docProps/app.xml
@@ -0,0 +1 @@
+Go DOCX
\ No newline at end of file
diff --git a/xml/docProps/core.xml b/xml/docProps/core.xml
new file mode 100644
index 0000000..8b2abf2
--- /dev/null
+++ b/xml/docProps/core.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/xml/word/styles.xml b/xml/word/styles.xml
new file mode 100644
index 0000000..455516c
--- /dev/null
+++ b/xml/word/styles.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/word/theme/theme1.xml b/xml/word/theme/theme1.xml
new file mode 100644
index 0000000..2bb59b7
--- /dev/null
+++ b/xml/word/theme/theme1.xml
@@ -0,0 +1,318 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file