1
0
mirror of https://github.com/fumiama/go-docx.git synced 2026-06-05 07:40:24 +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() {
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

View File

@@ -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

View File

@@ -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

2
fs.go
View File

@@ -4,6 +4,6 @@ import "embed"
var (
//go:embed xml
//go:embed xml/_rels/*
//go:embed xml/a4/_rels/*
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,
// 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}

View File

@@ -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)

View File

@@ -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 {