1
0
mirror of https://github.com/fumiama/go-docx.git synced 2026-06-27 14:40:24 +08:00

optimize: unpack

This commit is contained in:
源文雨
2023-02-09 19:24:50 +08:00
parent 56810d8288
commit 9aae5582ad

View File

@@ -5,7 +5,6 @@ import (
"archive/zip" "archive/zip"
"bytes" "bytes"
"encoding/xml" "encoding/xml"
"io"
) )
// This receives a zip file (word documents are a zip with multiple xml inside) // This receives a zip file (word documents are a zip with multiple xml inside)
@@ -16,63 +15,51 @@ func unpack(zipReader *zip.Reader) (docx *Docx, err error) {
docx = new(Docx) docx = new(Docx)
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 = processRelations(f, &docx.DocRelation) err = docx.parseDocRelation(f)
if err != nil { if err != nil {
return return
} }
} }
if f.Name == "word/document.xml" { if f.Name == "word/document.xml" {
err = processDoc(f, &docx.Document) err = docx.parseDocument(f)
if err != nil { if err != nil {
return return
} }
} }
} }
//TODO: find last rId
docx.buf = bytes.NewBuffer(make([]byte, 0, 1024*1024*4)) docx.buf = bytes.NewBuffer(make([]byte, 0, 1024*1024*4))
return return
} }
// Processes one of the relevant files, the one with the actual document // parseDocument processes one of the relevant files, the one with the actual document
func processDoc(file *zip.File, doc *Document) error { func (f *Docx) parseDocument(file *zip.File) error {
filebytes, err := readZipFile(file) zf, err := file.Open()
if err != nil { if err != nil {
return err return err
} }
defer zf.Close()
doc.XMLW = XMLNS_W f.Document.XMLW = XMLNS_W
doc.XMLR = XMLNS_R f.Document.XMLR = XMLNS_R
doc.XMLWP = XMLNS_WP f.Document.XMLWP = XMLNS_WP
doc.XMLName.Space = XMLNS_W f.Document.XMLName.Space = XMLNS_W
doc.XMLName.Local = "document" f.Document.XMLName.Local = "document"
err = xml.Unmarshal(filebytes, doc) err = xml.NewDecoder(zf).Decode(&f.Document)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// Processes one of the relevant files, the one with the relationships // parseDocRelation processes one of the relevant files, the one with the relationships
func processRelations(file *zip.File, rels *Relationships) error { func (f *Docx) parseDocRelation(file *zip.File) error {
filebytes, err := readZipFile(file) zf, err := file.Open()
if err != nil { if err != nil {
return err return err
} }
defer zf.Close()
rels.Xmlns = XMLNS_R f.DocRelation.Xmlns = XMLNS_R
err = xml.Unmarshal(filebytes, rels) //TODO: find last rId
if err != nil { return xml.NewDecoder(zf).Decode(&f.DocRelation)
return err
}
return nil
}
// From a zip file structure, we return a byte array
func readZipFile(zf *zip.File) ([]byte, error) {
f, err := zf.Open()
if err != nil {
return nil, err
}
defer f.Close()
return io.ReadAll(f)
} }