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

make lint happy

This commit is contained in:
源文雨
2023-02-23 14:34:44 +08:00
parent 59cce024f7
commit fa053fefd4
13 changed files with 350 additions and 170 deletions

View File

@@ -2,14 +2,14 @@ package docxlib
// AddParagraph adds a new paragraph
func (f *Docx) AddParagraph() *Paragraph {
p := &Paragraph{
f.Document.Body.mu.Lock()
defer f.Document.Body.mu.Unlock()
f.Document.Body.Paragraphs = append(f.Document.Body.Paragraphs, Paragraph{
Children: make([]interface{}, 0, 64),
file: f,
}
})
f.Document.Body.Paragraphs = append(f.Document.Body.Paragraphs, p)
return p
return &f.Document.Body.Paragraphs[len(f.Document.Body.Paragraphs)-1]
}
// Justification allows to set para's horizonal alignment

View File

@@ -15,16 +15,13 @@ func newEmptyA4File() *Docx {
XMLR: XMLNS_R,
XMLWP: XMLNS_WP,
// XMLWP14: XMLNS_WP14,
Body: &Body{
XMLName: xml.Name{
Space: "w",
},
Paragraphs: make([]*Paragraph, 0, 64),
Body: Body{
Paragraphs: make([]Paragraph, 0, 64),
},
},
DocRelation: Relationships{
Xmlns: XMLNS_REL,
Relationships: []*Relationship{
Relationship: []Relationship{
{
ID: "rId1",
Type: `http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles`,
@@ -69,6 +66,6 @@ func newEmptyA4File() *Docx {
},
buf: bytes.NewBuffer(make([]byte, 0, 1024*1024*4)),
}
docx.Document.file = docx
docx.Document.Body.file = docx
return docx
}

12
link.go
View File

@@ -17,14 +17,14 @@ var (
//
// this func is not thread-safe
func (f *Docx) addLinkRelation(link string) string {
rel := &Relationship{
rel := Relationship{
ID: "rId" + strconv.Itoa(int(atomic.AddUintptr(&f.rId, 1))),
Type: REL_HYPERLINK,
Target: link,
TargetMode: REL_TARGETMODE,
}
f.DocRelation.Relationships = append(f.DocRelation.Relationships, rel)
f.DocRelation.Relationship = append(f.DocRelation.Relationship, rel)
return rel.ID
}
@@ -33,13 +33,13 @@ func (f *Docx) addLinkRelation(link string) string {
//
// this func is not thread-safe
func (f *Docx) addImageRelation(m Media) string {
rel := &Relationship{
rel := Relationship{
ID: "rId" + strconv.Itoa(int(atomic.AddUintptr(&f.rId, 1))),
Type: REL_IMAGE,
Target: "media/" + m.Name,
}
f.DocRelation.Relationships = append(f.DocRelation.Relationships, rel)
f.DocRelation.Relationship = append(f.DocRelation.Relationship, rel)
return rel.ID
}
@@ -48,7 +48,7 @@ func (f *Docx) addImageRelation(m Media) string {
func (f *Docx) ReferTarget(id string) (string, error) {
f.DocRelation.mu.RLock()
defer f.DocRelation.mu.RUnlock()
for _, a := range f.DocRelation.Relationships {
for _, a := range f.DocRelation.Relationship {
if a.ID == id {
return a.Target, nil
}
@@ -60,7 +60,7 @@ func (f *Docx) ReferTarget(id string) (string, error) {
func (f *Docx) ReferID(target string) (string, error) {
f.DocRelation.mu.RLock()
defer f.DocRelation.mu.RUnlock()
for _, a := range f.DocRelation.Relationships {
for _, a := range f.DocRelation.Relationship {
if a.Target == target {
return a.ID, nil
}

View File

@@ -31,7 +31,7 @@ func (f *Docx) pack(zipWriter *zip.Writer) (err error) {
}
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}
for _, m := range f.media {
files[m.String()] = bytes.NewReader(m.Data)

View File

@@ -3,6 +3,8 @@ package docxlib
import (
"encoding/xml"
"io"
"strings"
"sync"
)
const (
@@ -24,27 +26,13 @@ func getAtt(atts []xml.Attr, name string) string {
}
type Body struct {
XMLName xml.Name `xml:"w:body"`
Paragraphs []*Paragraph `xml:"w:p,omitempty"`
}
type Document struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main document"`
XMLW string `xml:"xmlns:w,attr"` // cannot be unmarshalled in
XMLR string `xml:"xmlns:r,attr,omitempty"` // cannot be unmarshalled in
XMLWP string `xml:"xmlns:wp,attr,omitempty"` // cannot be unmarshalled in
XMLWP14 string `xml:"xmlns:wp14,attr,omitempty"` // cannot be unmarshalled in
Body *Body
mu sync.Mutex
Paragraphs []Paragraph `xml:"w:p,omitempty"`
file *Docx
}
func (doc *Document) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
if doc.Body == nil {
doc.Body = &Body{
Paragraphs: make([]*Paragraph, 0, 64),
}
}
func (b *Body) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err == io.EOF {
@@ -56,19 +44,59 @@ func (doc *Document) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
switch tt := t.(type) {
case xml.StartElement:
switch tt.Name.Local {
case "body":
case "p":
if tt.Name.Local == "p" {
var value Paragraph
d.DecodeElement(&value, &tt)
if len(value.Children) > 0 {
value.file = doc.file
doc.Body.Paragraphs = append(doc.Body.Paragraphs, &value)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
if len(value.Children) > 0 {
value.file = b.file
b.mu.Lock()
b.Paragraphs = append(b.Paragraphs, value)
b.mu.Unlock()
}
default:
d.Skip()
continue
}
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
}
}
return nil
}
type Document struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main document"`
XMLW string `xml:"xmlns:w,attr"` // cannot be unmarshalled in
XMLR string `xml:"xmlns:r,attr,omitempty"` // cannot be unmarshalled in
XMLWP string `xml:"xmlns:wp,attr,omitempty"` // cannot be unmarshalled in
// XMLWP14 string `xml:"xmlns:wp14,attr,omitempty"` // cannot be unmarshalled in
Body Body `xml:"w:body"`
}
func (doc *Document) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err == io.EOF {
break
}
if err != nil {
return err
}
switch tt := t.(type) {
case xml.StartElement:
if tt.Name.Local == "body" {
err = d.DecodeElement(&doc.Body, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
}
}
}

View File

@@ -2,9 +2,6 @@ package docxlib
import (
"encoding/xml"
"hash/crc64"
"io"
"os"
"testing"
)
@@ -47,76 +44,3 @@ func TestUnmarshalPlainStructure(t *testing.T) {
}
}
}
func TestInlineDrawingStructure(t *testing.T) {
w := NewA4()
// add new paragraph
para1 := w.AddParagraph()
// add text
para1.AddText("直接粘贴 inline").AddTab()
r, err := para1.AddAnchorDrawingFrom("testdata/fumiama.JPG")
if err != nil {
t.Fatal(err)
}
r.Drawing.Anchor.Graphic.GraphicData.Pic.BlipFill.Blip.AlphaModFix = &AAlphaModFix{Amount: 50000}
r.Drawing.Anchor.Graphic.GraphicData.Pic.NonVisualPicProperties.CNvPicPr.Locks = &APicLocks{NoChangeAspect: 1}
r.Drawing.Anchor.Graphic.GraphicData.Pic.SpPr.Xfrm.Rot = 50000
para2 := w.AddParagraph().Justification("center")
para2.AddInlineDrawingFrom("testdata/fumiama.JPG")
para2.AddTab().AddTab().AppendTab().AppendTab()
para2.AddInlineDrawingFrom("testdata/fumiama2x.webp")
para3 := w.AddParagraph()
para3.AddInlineDrawingFrom("testdata/fumiamayoko.png")
f, err := os.Create("TestMarshalInlineDrawingStructure.xml")
if err != nil {
t.Fatal(err)
}
defer f.Close()
_, err = marshaller{data: w.Document}.WriteTo(f)
if err != nil {
t.Fatal(err)
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
t.Fatal(err)
}
w = NewA4()
err = xml.NewDecoder(f).Decode(&w.Document)
if err != nil {
t.Fatal(err)
}
f1, err := os.Create("TestUnmarshalInlineDrawingStructure.xml")
if err != nil {
t.Fatal(err)
}
defer f1.Close()
_, err = marshaller{data: w.Document}.WriteTo(f1)
if err != nil {
t.Fatal(err)
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
t.Fatal(err)
}
_, err = f1.Seek(0, io.SeekStart)
if err != nil {
t.Fatal(err)
}
h := crc64.New(crc64.MakeTable(crc64.ECMA))
_, err = io.Copy(h, f)
if err != nil {
t.Fatal(err)
}
md51 := h.Sum64()
h.Reset()
_, err = io.Copy(h, f1)
if err != nil {
t.Fatal(err)
}
md52 := h.Sum64()
if md51 != md52 {
t.Fail()
}
}

View File

@@ -4,6 +4,7 @@ import (
"encoding/xml"
"io"
"strconv"
"strings"
)
const (
@@ -38,10 +39,16 @@ func (r *Drawing) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch tt.Name.Local {
case "inline":
r.Inline = new(WPInline)
d.DecodeElement(r.Inline, &tt)
err = d.DecodeElement(r.Inline, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "anchor":
r.Anchor = new(WPAnchor)
d.DecodeElement(r.Anchor, &tt)
err = d.DecodeElement(r.Anchor, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
default:
continue
}
@@ -138,14 +145,23 @@ func (r *WPInline) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err err
}
case "docPr":
r.DocPr = new(WPDocPr)
d.DecodeElement(r.DocPr, &tt)
err = d.DecodeElement(r.DocPr, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "cNvGraphicFramePr":
var value WPCNvGraphicFramePr
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.CNvGraphicFramePr = &value
case "graphic":
var value AGraphic
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.Graphic = &value
default:
continue
@@ -285,7 +301,10 @@ func (w *WPCNvGraphicFramePr) UnmarshalXML(d *xml.Decoder, start xml.StartElemen
switch tt.Name.Local {
case "graphicFrameLocks":
var value AGraphicFrameLocks
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
value.NoChangeAspect, err = strconv.Atoi(getAtt(tt.Attr, "noChangeAspect"))
if err != nil {
return err
@@ -336,7 +355,10 @@ func (a *AGraphic) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch tt.Name.Local {
case "graphicData":
var value AGraphicData
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
value.URI = getAtt(tt.Attr, "uri")
a.GraphicData = &value
default:
@@ -370,7 +392,10 @@ func (a *AGraphicData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) erro
switch tt.Name.Local {
case "pic":
var value PICPic
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
value.XMLPIC = getAtt(tt.Attr, "pic")
a.Pic = &value
default:
@@ -406,15 +431,24 @@ func (p *PICPic) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch tt.Name.Local {
case "nvPicPr":
var value PICNonVisualPicProperties
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
p.NonVisualPicProperties = &value
case "blipFill":
var value PICBlipFill
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
p.BlipFill = &value
case "spPr":
var value PICSpPr
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
p.SpPr = &value
default:
continue
@@ -449,7 +483,10 @@ func (p *PICNonVisualPicProperties) UnmarshalXML(d *xml.Decoder, start xml.Start
p.NonVisualDrawingProperties.ID = getAtt(tt.Attr, "id")
p.NonVisualDrawingProperties.Name = getAtt(tt.Attr, "name")
case "cNvPicPr":
d.DecodeElement(&p.CNvPicPr, &tt)
err = d.DecodeElement(&p.CNvPicPr, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
default:
continue
}
@@ -529,9 +566,15 @@ func (p *PICBlipFill) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
case xml.StartElement:
switch tt.Name.Local {
case "blip":
d.DecodeElement(&p.Blip, &tt)
err = d.DecodeElement(&p.Blip, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "stretch":
d.DecodeElement(&p.Stretch, &tt)
err = d.DecodeElement(&p.Stretch, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
default:
continue
}
@@ -626,9 +669,15 @@ func (p *PICSpPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
case xml.StartElement:
switch tt.Name.Local {
case "xfrm":
d.DecodeElement(&p.Xfrm, &tt)
err = d.DecodeElement(&p.Xfrm, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "prstGeom":
d.DecodeElement(&p.PrstGeom, &tt)
err = d.DecodeElement(&p.PrstGeom, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
p.PrstGeom.Prst = getAtt(tt.Attr, "prst")
default:
continue
@@ -881,17 +930,29 @@ func (r *WPAnchor) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err err
case "positionH":
r.PositionH = new(WPPositionH)
// r.PositionH.RelativeFrom = getAtt(tt.Attr, "relativeFrom")
d.DecodeElement(&r.PositionH, &tt)
err = d.DecodeElement(&r.PositionH, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "positionV":
r.PositionV = new(WPPositionV)
// r.PositionV.RelativeFrom = getAtt(tt.Attr, "relativeFrom")
d.DecodeElement(&r.PositionV, &tt)
err = d.DecodeElement(&r.PositionV, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "extent":
r.Extent = new(WPExtent)
d.DecodeElement(&r.Extent, &tt)
err = d.DecodeElement(&r.Extent, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "effectExtent":
r.EffectExtent = new(WPEffectExtent)
d.DecodeElement(&r.EffectExtent, &tt)
err = d.DecodeElement(&r.EffectExtent, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "wrapNone":
r.WrapNone = &struct{}{}
case "wrapSquare":
@@ -899,13 +960,22 @@ func (r *WPAnchor) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err err
r.WrapSquare.WrapText = getAtt(tt.Attr, "wrapText")
case "docPr":
r.DocPr = new(WPDocPr)
d.DecodeElement(r.DocPr, &tt)
err = d.DecodeElement(r.DocPr, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "cNvGraphicFramePr":
r.CNvGraphicFramePr = new(WPCNvGraphicFramePr)
d.DecodeElement(r.CNvGraphicFramePr, &tt)
err = d.DecodeElement(r.CNvGraphicFramePr, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "graphic":
r.Graphic = new(AGraphic)
d.DecodeElement(&r.Graphic, &tt)
err = d.DecodeElement(&r.Graphic, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
default:
continue
}
@@ -949,7 +1019,7 @@ func (r *WPPositionH) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
switch tt.Name.Local {
case "posOffset":
err = d.DecodeElement(&r.PosOffset, &tt)
if err != nil {
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
default:
@@ -988,7 +1058,7 @@ func (r *WPPositionV) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
switch tt.Name.Local {
case "posOffset":
err = d.DecodeElement(&r.PosOffset, &tt)
if err != nil {
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
default:

82
structdrawing_test.go Normal file
View File

@@ -0,0 +1,82 @@
package docxlib
import (
"encoding/xml"
"hash/crc64"
"io"
"os"
"testing"
)
func TestDrawingStructure(t *testing.T) {
w := NewA4()
// add new paragraph
para1 := w.AddParagraph()
// add text
para1.AddText("直接粘贴 inline").AddTab()
r, err := para1.AddAnchorDrawingFrom("testdata/fumiama.JPG")
if err != nil {
t.Fatal(err)
}
r.Drawing.Anchor.Graphic.GraphicData.Pic.BlipFill.Blip.AlphaModFix = &AAlphaModFix{Amount: 50000}
r.Drawing.Anchor.Graphic.GraphicData.Pic.NonVisualPicProperties.CNvPicPr.Locks = &APicLocks{NoChangeAspect: 1}
r.Drawing.Anchor.Graphic.GraphicData.Pic.SpPr.Xfrm.Rot = 50000
para2 := w.AddParagraph().Justification("center")
para2.AddInlineDrawingFrom("testdata/fumiama.JPG")
para2.AddTab().AddTab().AppendTab().AppendTab()
para2.AddInlineDrawingFrom("testdata/fumiama2x.webp")
para3 := w.AddParagraph()
para3.AddInlineDrawingFrom("testdata/fumiamayoko.png")
f, err := os.Create("TestMarshalInlineDrawingStructure.xml")
if err != nil {
t.Fatal(err)
}
defer f.Close()
_, err = marshaller{data: &w.Document}.WriteTo(f)
if err != nil {
t.Fatal(err)
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
t.Fatal(err)
}
w = NewA4()
err = xml.NewDecoder(f).Decode(&w.Document)
if err != nil {
t.Fatal(err)
}
f1, err := os.Create("TestUnmarshalInlineDrawingStructure.xml")
if err != nil {
t.Fatal(err)
}
defer f1.Close()
_, err = marshaller{data: &w.Document}.WriteTo(f1)
if err != nil {
t.Fatal(err)
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
t.Fatal(err)
}
_, err = f1.Seek(0, io.SeekStart)
if err != nil {
t.Fatal(err)
}
h := crc64.New(crc64.MakeTable(crc64.ECMA))
_, err = io.Copy(h, f)
if err != nil {
t.Fatal(err)
}
crc1 := h.Sum64()
h.Reset()
_, err = io.Copy(h, f1)
if err != nil {
t.Fatal(err)
}
crc2 := h.Sum64()
if crc1 != crc2 {
t.Fail()
}
}

View File

@@ -3,6 +3,7 @@ package docxlib
import (
"encoding/xml"
"io"
"strings"
)
// Hyperlink element contains links
@@ -25,9 +26,10 @@ func (r *Hyperlink) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch tt := t.(type) {
case xml.StartElement:
if tt.Name.Local == "r" {
d.DecodeElement(&r.Run, &tt)
} else {
continue
err = d.DecodeElement(&r.Run, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
}
}

View File

@@ -36,7 +36,7 @@ func (p *ParagraphProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElemen
}
type Paragraph struct {
XMLName xml.Name `xml:"w:p,omitempty"`
// XMLName xml.Name `xml:"w:p,omitempty"`
Properties *ParagraphProperties
Children []interface{} // Children will generate an unnecessary tag <Children> ... </Children> and we skip it by a self-defined xml.Marshaler
@@ -106,7 +106,10 @@ func (p *Paragraph) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch tt.Name.Local {
case "hyperlink":
var value Hyperlink
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
id := getAtt(tt.Attr, "id")
anchor := getAtt(tt.Attr, "anchor")
if id != "" {
@@ -118,15 +121,24 @@ func (p *Paragraph) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
elem = &value
case "r":
var value Run
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
elem = &value
case "rPr":
var value RunProperties
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
elem = &value
case "pPr":
var value ParagraphProperties
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
p.Properties = &value
continue
default:

View File

@@ -1,7 +1,6 @@
package docxlib
import (
"encoding/xml"
"sync"
)
@@ -14,16 +13,14 @@ const (
)
type Relationships struct {
mu sync.RWMutex
XMLName xml.Name `xml:"Relationships"`
Xmlns string `xml:"xmlns,attr"`
Relationships []*Relationship `xml:"Relationship"`
mu sync.RWMutex
Xmlns string `xml:"xmlns,attr"`
Relationship []Relationship
}
type Relationship struct {
XMLName xml.Name `xml:"Relationship"`
ID string `xml:"Id,attr"`
Type string `xml:"Type,attr"`
Target string `xml:"Target,attr"`
TargetMode string `xml:"TargetMode,attr,omitempty"`
ID string `xml:"Id,attr"`
Type string `xml:"Type,attr"`
Target string `xml:"Target,attr"`
TargetMode string `xml:"TargetMode,attr,omitempty"`
}

55
structrel_test.go Normal file
View File

@@ -0,0 +1,55 @@
package docxlib
import (
"crypto/md5"
"encoding/hex"
"io"
"os"
"testing"
)
func TestRelationships(t *testing.T) {
rel := Relationships{
Xmlns: XMLNS_REL,
Relationship: []Relationship{
{
ID: "rId1",
Type: `http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles`,
Target: "styles.xml",
},
{
ID: "rId2",
Type: `http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme`,
Target: "theme/theme1.xml",
},
{
ID: "rId3",
Type: `http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable`,
Target: "fontTable.xml",
},
{
ID: "rId4",
Type: `http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings`,
Target: "settings.xml",
},
{
ID: "rId5",
Type: `http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings`,
Target: "webSettings.xml",
},
},
}
f, err := os.Create("TestRelationships.xml")
if err != nil {
t.Fatal(err)
}
h := md5.New()
_, err = io.Copy(io.MultiWriter(f, h), marshaller{data: &rel})
if err != nil {
t.Fatal(err)
}
m := hex.EncodeToString(h.Sum(make([]byte, 0, 16)))
if m != "c75af73ef6cc9536a193669c4a3605c3" {
t.Fatal("real md5:", m)
}
}

View File

@@ -3,6 +3,7 @@ package docxlib
import (
"encoding/xml"
"io"
"strings"
)
// Run is part of a paragraph that has its own style. It could be
@@ -36,19 +37,31 @@ func (r *Run) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch tt.Name.Local {
case "rPr":
var value RunProperties
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.RunProperties = &value
case "instrText":
var value string
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.InstrText = value
case "t":
var value Text
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.Text = &value
case "drawing":
var value Drawing
d.DecodeElement(&value, &tt)
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.Drawing = &value
case "tab":
if r.InstrText == "" && r.Text == nil && r.Drawing == nil {
@@ -159,6 +172,6 @@ type Size struct {
// both两端对齐。
// distribute分散对齐。
type Justification struct {
XMLName xml.Name `xml:"w:jc"`
Val string `xml:"w:val,attr"`
// XMLName xml.Name `xml:"w:jc"`
Val string `xml:"w:val,attr"`
}