From 585ee6cda8f49dae9f468f7dc8c1f752f22537aa 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: Tue, 21 Feb 2023 13:14:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=99=AE=E9=80=82=E5=8C=96=20template?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/main/main.go | 2 +- docxlib.go | 12 +++++++++--- empty.go | 13 +++++++++++-- fs.go | 2 +- pack.go | 26 ++++++++++++++------------ structdoc_test.go | 4 ++-- unpack.go | 20 +++++++++++++------- xml/{ => a4}/[Content_Types].xml | 0 xml/{ => a4}/_rels/.rels | 0 xml/{ => a4}/docProps/app.xml | 0 xml/{ => a4}/docProps/core.xml | 0 xml/{ => a4}/word/styles.xml | 0 xml/{ => a4}/word/theme/theme1.xml | 0 13 files changed, 51 insertions(+), 28 deletions(-) rename xml/{ => a4}/[Content_Types].xml (100%) rename xml/{ => a4}/_rels/.rels (100%) rename xml/{ => a4}/docProps/app.xml (100%) rename xml/{ => a4}/docProps/core.xml (100%) rename xml/{ => a4}/word/styles.xml (100%) rename xml/{ => a4}/word/theme/theme1.xml (100%) diff --git a/cmd/main/main.go b/cmd/main/main.go index edc9ad4..ca8db9a 100644 --- a/cmd/main/main.go +++ b/cmd/main/main.go @@ -17,7 +17,7 @@ func init() { func main() { fmt.Printf("Preparing new document to write at %s\n", *fileLocation) - w := docxlib.New() + w := docxlib.NewA4() // add new paragraph para1 := w.AddParagraph() // add text diff --git a/docxlib.go b/docxlib.go index 62bdba0..35051bf 100644 --- a/docxlib.go +++ b/docxlib.go @@ -5,6 +5,7 @@ import ( "bytes" "errors" "io" + "io/fs" ) var ( @@ -24,16 +25,21 @@ type Docx struct { rId uintptr imageId uintptr + template string + tmplfs fs.FS + tmpfslst []string + buf *bytes.Buffer isbufempty bool + io.Reader io.WriterTo } -// New generates a new empty docx file that we can manipulate and +// NewA4 generates a new empty A4 docx file that we can manipulate and // later on, save -func New() *Docx { - return newEmptyFile() +func NewA4() *Docx { + return newEmptyA4File() } // Parse generates a new docx file in memory from a reader diff --git a/empty.go b/empty.go index 27c68d8..94ed4a6 100644 --- a/empty.go +++ b/empty.go @@ -5,7 +5,7 @@ import ( "encoding/xml" ) -func newEmptyFile() *Docx { +func newEmptyA4File() *Docx { docx := &Docx{ Document: Document{ XMLName: xml.Name{ @@ -45,7 +45,16 @@ func newEmptyFile() *Docx { media: make([]Media, 0, 64), mediaNameIdx: make(map[string]int, 64), rId: 3, - buf: bytes.NewBuffer(make([]byte, 0, 1024*1024*4)), + template: "a4", + tmpfslst: []string{ + "_rels/.rels", + "docProps/app.xml", + "docProps/core.xml", + "word/theme/theme1.xml", + "word/styles.xml", + "[Content_Types].xml", + }, + buf: bytes.NewBuffer(make([]byte, 0, 1024*1024*4)), } docx.Document.file = docx return docx diff --git a/fs.go b/fs.go index 4b09dac..beccd49 100644 --- a/fs.go +++ b/fs.go @@ -4,6 +4,6 @@ import "embed" var ( //go:embed xml - //go:embed xml/_rels/* + //go:embed xml/a4/_rels/* TEMP_XML_FS embed.FS ) diff --git a/pack.go b/pack.go index bd7efbb..343b5da 100644 --- a/pack.go +++ b/pack.go @@ -12,22 +12,24 @@ import ( // 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) { - fileslst := []string{ - "_rels/.rels", - "docProps/app.xml", - "docProps/core.xml", - "word/theme/theme1.xml", - "word/styles.xml", - "[Content_Types].xml", - } files := make(map[string]io.Reader, 64) - for _, name := range fileslst { - files[name], err = TEMP_XML_FS.Open("xml/" + name) - if err != nil { - return + if f.template != "" { + for _, name := range f.tmpfslst { + files[name], err = TEMP_XML_FS.Open("xml/" + f.template + "/" + name) + if err != nil { + return + } + } + } else { + for _, name := range f.tmpfslst { + files[name], err = f.tmplfs.Open(name) + if err != nil { + return + } } } + files["word/_rels/document.xml.rels"] = marshaller{data: &f.DocRelation} files["word/document.xml"] = marshaller{data: f.Document} diff --git a/structdoc_test.go b/structdoc_test.go index 2f6b514..f9fa4fa 100644 --- a/structdoc_test.go +++ b/structdoc_test.go @@ -568,7 +568,7 @@ func TestUnmarshalDrawingStructure(t *testing.T) { } func TestMarshalDrawingStructure(t *testing.T) { - w := New() + w := NewA4() // add new paragraph para1 := w.AddParagraph() // add text @@ -594,7 +594,7 @@ func TestMarshalDrawingStructure(t *testing.T) { if err != nil { t.Fatal(err) } - w = New() + w = NewA4() err = xml.NewDecoder(f).Decode(&w.Document) if err != nil { t.Fatal(err) diff --git a/unpack.go b/unpack.go index c7b6581..e807af0 100644 --- a/unpack.go +++ b/unpack.go @@ -16,23 +16,32 @@ import ( func unpack(zipReader *zip.Reader) (docx *Docx, err error) { docx = new(Docx) docx.mediaNameIdx = make(map[string]int, 64) + docx.tmplfs = zipReader + docx.tmpfslst = make([]string, 0, 64) for _, f := range zipReader.File { if f.Name == "word/_rels/document.xml.rels" { err = docx.parseDocRelation(f) if err != nil { return } + continue } if f.Name == "word/document.xml" { err = docx.parseDocument(f) if err != nil { return } + continue } - err = docx.checkAndParseMedia(f) - if err != nil { - return + if strings.HasPrefix(f.Name, MEDIA_FOLDER) { + err = docx.parseMedia(f) + if err != nil { + return + } + continue } + // fill remaining files into tmpfslst + docx.tmpfslst = append(docx.tmpfslst, f.Name) } docx.buf = bytes.NewBuffer(make([]byte, 0, 1024*1024*4)) return @@ -72,10 +81,7 @@ func (f *Docx) parseDocRelation(file *zip.File) error { return xml.NewDecoder(zf).Decode(&f.DocRelation) } -func (f *Docx) checkAndParseMedia(file *zip.File) error { - if !strings.HasPrefix(file.Name, MEDIA_FOLDER) { - return nil - } +func (f *Docx) parseMedia(file *zip.File) error { name := file.Name[len(MEDIA_FOLDER):] zf, err := file.Open() if err != nil { diff --git a/xml/[Content_Types].xml b/xml/a4/[Content_Types].xml similarity index 100% rename from xml/[Content_Types].xml rename to xml/a4/[Content_Types].xml diff --git a/xml/_rels/.rels b/xml/a4/_rels/.rels similarity index 100% rename from xml/_rels/.rels rename to xml/a4/_rels/.rels diff --git a/xml/docProps/app.xml b/xml/a4/docProps/app.xml similarity index 100% rename from xml/docProps/app.xml rename to xml/a4/docProps/app.xml diff --git a/xml/docProps/core.xml b/xml/a4/docProps/core.xml similarity index 100% rename from xml/docProps/core.xml rename to xml/a4/docProps/core.xml diff --git a/xml/word/styles.xml b/xml/a4/word/styles.xml similarity index 100% rename from xml/word/styles.xml rename to xml/a4/word/styles.xml diff --git a/xml/word/theme/theme1.xml b/xml/a4/word/theme/theme1.xml similarity index 100% rename from xml/word/theme/theme1.xml rename to xml/a4/word/theme/theme1.xml