1
0
mirror of https://github.com/fumiama/go-docx.git synced 2026-06-19 09:00:31 +08:00

普适化 template

This commit is contained in:
源文雨
2023-02-21 13:14:21 +08:00
parent 092b86e7f4
commit 585ee6cda8
13 changed files with 51 additions and 28 deletions

View File

@@ -17,7 +17,7 @@ func init() {
func main() { func main() {
fmt.Printf("Preparing new document to write at %s\n", *fileLocation) fmt.Printf("Preparing new document to write at %s\n", *fileLocation)
w := docxlib.New() w := docxlib.NewA4()
// add new paragraph // add new paragraph
para1 := w.AddParagraph() para1 := w.AddParagraph()
// add text // add text

View File

@@ -5,6 +5,7 @@ import (
"bytes" "bytes"
"errors" "errors"
"io" "io"
"io/fs"
) )
var ( var (
@@ -24,16 +25,21 @@ type Docx struct {
rId uintptr rId uintptr
imageId uintptr imageId uintptr
template string
tmplfs fs.FS
tmpfslst []string
buf *bytes.Buffer buf *bytes.Buffer
isbufempty bool isbufempty bool
io.Reader io.Reader
io.WriterTo 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 // later on, save
func New() *Docx { func NewA4() *Docx {
return newEmptyFile() return newEmptyA4File()
} }
// Parse generates a new docx file in memory from a reader // Parse generates a new docx file in memory from a reader

View File

@@ -5,7 +5,7 @@ import (
"encoding/xml" "encoding/xml"
) )
func newEmptyFile() *Docx { func newEmptyA4File() *Docx {
docx := &Docx{ docx := &Docx{
Document: Document{ Document: Document{
XMLName: xml.Name{ XMLName: xml.Name{
@@ -45,7 +45,16 @@ func newEmptyFile() *Docx {
media: make([]Media, 0, 64), media: make([]Media, 0, 64),
mediaNameIdx: make(map[string]int, 64), mediaNameIdx: make(map[string]int, 64),
rId: 3, 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 docx.Document.file = docx
return docx return docx

2
fs.go
View File

@@ -4,6 +4,6 @@ import "embed"
var ( var (
//go:embed xml //go:embed xml
//go:embed xml/_rels/* //go:embed xml/a4/_rels/*
TEMP_XML_FS embed.FS TEMP_XML_FS embed.FS
) )

26
pack.go
View File

@@ -12,22 +12,24 @@ import (
// and writes the relevant files. Some of them come from the empty_constants file, // and writes the relevant files. Some of them come from the empty_constants file,
// others from the actual in-memory structure // others from the actual in-memory structure
func (f *Docx) pack(zipWriter *zip.Writer) (err error) { 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) files := make(map[string]io.Reader, 64)
for _, name := range fileslst { if f.template != "" {
files[name], err = TEMP_XML_FS.Open("xml/" + name) for _, name := range f.tmpfslst {
if err != nil { files[name], err = TEMP_XML_FS.Open("xml/" + f.template + "/" + name)
return 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/_rels/document.xml.rels"] = marshaller{data: &f.DocRelation}
files["word/document.xml"] = marshaller{data: f.Document} files["word/document.xml"] = marshaller{data: f.Document}

View File

@@ -568,7 +568,7 @@ func TestUnmarshalDrawingStructure(t *testing.T) {
} }
func TestMarshalDrawingStructure(t *testing.T) { func TestMarshalDrawingStructure(t *testing.T) {
w := New() w := NewA4()
// add new paragraph // add new paragraph
para1 := w.AddParagraph() para1 := w.AddParagraph()
// add text // add text
@@ -594,7 +594,7 @@ func TestMarshalDrawingStructure(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
w = New() w = NewA4()
err = xml.NewDecoder(f).Decode(&w.Document) err = xml.NewDecoder(f).Decode(&w.Document)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@@ -16,23 +16,32 @@ import (
func unpack(zipReader *zip.Reader) (docx *Docx, err error) { func unpack(zipReader *zip.Reader) (docx *Docx, err error) {
docx = new(Docx) docx = new(Docx)
docx.mediaNameIdx = make(map[string]int, 64) docx.mediaNameIdx = make(map[string]int, 64)
docx.tmplfs = zipReader
docx.tmpfslst = make([]string, 0, 64)
for _, f := range zipReader.File { for _, f := range zipReader.File {
if f.Name == "word/_rels/document.xml.rels" { if f.Name == "word/_rels/document.xml.rels" {
err = docx.parseDocRelation(f) err = docx.parseDocRelation(f)
if err != nil { if err != nil {
return return
} }
continue
} }
if f.Name == "word/document.xml" { if f.Name == "word/document.xml" {
err = docx.parseDocument(f) err = docx.parseDocument(f)
if err != nil { if err != nil {
return return
} }
continue
} }
err = docx.checkAndParseMedia(f) if strings.HasPrefix(f.Name, MEDIA_FOLDER) {
if err != nil { err = docx.parseMedia(f)
return 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)) docx.buf = bytes.NewBuffer(make([]byte, 0, 1024*1024*4))
return return
@@ -72,10 +81,7 @@ func (f *Docx) parseDocRelation(file *zip.File) error {
return xml.NewDecoder(zf).Decode(&f.DocRelation) return xml.NewDecoder(zf).Decode(&f.DocRelation)
} }
func (f *Docx) checkAndParseMedia(file *zip.File) error { func (f *Docx) parseMedia(file *zip.File) error {
if !strings.HasPrefix(file.Name, MEDIA_FOLDER) {
return nil
}
name := file.Name[len(MEDIA_FOLDER):] name := file.Name[len(MEDIA_FOLDER):]
zf, err := file.Open() zf, err := file.Open()
if err != nil { if err != nil {