mirror of
https://github.com/fumiama/go-docx.git
synced 2026-06-05 07:40:24 +08:00
普适化 template
This commit is contained in:
@@ -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
|
||||
|
||||
12
docxlib.go
12
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
|
||||
|
||||
13
empty.go
13
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
|
||||
|
||||
2
fs.go
2
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
|
||||
)
|
||||
|
||||
26
pack.go
26
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}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
20
unpack.go
20
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 {
|
||||
|
||||
Reference in New Issue
Block a user