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

add: wpc & more w:ln

This commit is contained in:
源文雨
2023-03-01 21:26:05 +08:00
parent 1b84ef3cf2
commit fa6f03aaff
8 changed files with 235 additions and 11 deletions

View File

@@ -130,8 +130,8 @@ func main() {
W: 9525,
SolidFill: &docx.ASolidFill{SrgbClr: &docx.ASrgbClr{Val: "000000"}},
Round: &struct{}{},
HeadEnd: &struct{}{},
TailEnd: &struct{}{},
HeadEnd: &docx.AHeadEnd{},
TailEnd: &docx.ATailEnd{},
},
})

View File

@@ -35,6 +35,7 @@ func newEmptyA4File() *Docx {
XMLR: XMLNS_R,
XMLWP: XMLNS_WP,
XMLWPS: XMLNS_WPS,
XMLWPC: XMLNS_WPC,
// XMLMC: XMLNS_MC,
// XMLWP14: XMLNS_WP14,
Body: Body{

2
id.go
View File

@@ -2,7 +2,7 @@ package docx
func (f *Docx) IncreaseID(name string) (n uintptr) {
f.slowIDsMu.Lock()
n, _ = f.slowIDs[name] //nolint: go-staticcheck
n = f.slowIDs[name]
n++
f.slowIDs[name] = n
f.slowIDsMu.Unlock()

127
structcanvas.go Normal file
View File

@@ -0,0 +1,127 @@
package docx
import (
"encoding/xml"
"io"
"strings"
)
type WordprocessingCanvas struct {
XMLName xml.Name `xml:"wpc:wpc,omitempty"`
Background *WPCBackground
Whole *WPCWhole
Items []interface{}
}
// UnmarshalXML ...
func (c *WordprocessingCanvas) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
for {
t, err := d.Token()
if err == io.EOF {
break
}
if err != nil {
return err
}
if tt, ok := t.(xml.StartElement); ok {
switch tt.Name.Local {
case "bg":
c.Background = new(WPCBackground)
err = d.DecodeElement(c.Background, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "whole":
c.Whole = new(WPCWhole)
err = d.DecodeElement(c.Whole, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "wsp":
var value WPSWordprocessingShape
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
c.Items = append(c.Items, &value)
default:
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
continue
}
}
}
return nil
}
type WPCBackground struct {
XMLName xml.Name `xml:"wpc:bg,omitempty"`
NoFill *struct{} `xml:"a:noFill,omitempty"`
}
// UnmarshalXML ...
func (b *WPCBackground) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
for {
t, err := d.Token()
if err == io.EOF {
break
}
if err != nil {
return err
}
if tt, ok := t.(xml.StartElement); ok {
switch tt.Name.Local {
case "noFill":
b.NoFill = &struct{}{}
default:
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
continue
}
}
}
return nil
}
type WPCWhole struct {
XMLName xml.Name `xml:"wpc:whole,omitempty"`
Line *ALine
}
// UnmarshalXML ...
func (w *WPCWhole) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
for {
t, err := d.Token()
if err == io.EOF {
break
}
if err != nil {
return err
}
if tt, ok := t.(xml.StartElement); ok {
switch tt.Name.Local {
case "ln":
w.Line = new(ALine)
err = d.DecodeElement(w.Line, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
default:
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
continue
}
}
}
return nil
}

View File

@@ -32,6 +32,7 @@ const (
XMLNS_R = `http://schemas.openxmlformats.org/officeDocument/2006/relationships`
XMLNS_WP = `http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing`
XMLNS_WPS = `http://schemas.microsoft.com/office/word/2010/wordprocessingShape`
XMLNS_WPC = `http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas`
// XMLNS_MC = `http://schemas.openxmlformats.org/markup-compatibility/2006`
// XMLNS_WP14 = `http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing`
@@ -101,6 +102,7 @@ type Document struct {
XMLR string `xml:"xmlns:r,attr,omitempty"` // cannot be unmarshalled in
XMLWP string `xml:"xmlns:wp,attr,omitempty"` // cannot be unmarshalled in
XMLWPS string `xml:"xmlns:wps,attr,omitempty"` // cannot be unmarshalled in
XMLWPC string `xml:"xmlns:wpc,attr,omitempty"` // cannot be unmarshalled in
// XMLMC string `xml:"xmlns:mc,attr,omitempty"` // cannot be unmarshalled in
// XMLWP14 string `xml:"xmlns:wp14,attr,omitempty"` // cannot be unmarshalled in

View File

@@ -152,13 +152,18 @@ func (w *WPSSpPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
// ALine represents a line element in a Word document.
type ALine struct {
XMLName xml.Name `xml:"a:ln,omitempty"`
W int64 `xml:"w,attr"`
XMLName xml.Name `xml:"a:ln,omitempty"`
W int64 `xml:"w,attr"`
Cap string `xml:"cap,attr,omitempty"`
Compound string `xml:"cmpd,attr,omitempty"`
Align string `xml:"algn,attr,omitempty"`
SolidFill *ASolidFill
PrstDash *APrstDash
Miter *AMiter
Round *struct{} `xml:"a:round,omitempty"`
HeadEnd *struct{} `xml:"a:headEnd,omitempty"`
TailEnd *struct{} `xml:"a:tailEnd,omitempty"`
HeadEnd *AHeadEnd
TailEnd *ATailEnd
}
// UnmarshalXML ...
@@ -170,6 +175,12 @@ func (l *ALine) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error)
if err != nil {
return err
}
case "cap":
l.Cap = attr.Value
case "cmpd":
l.Compound = attr.Value
case "algn":
l.Align = attr.Value
default:
// ignore other attributes
}
@@ -191,12 +202,28 @@ func (l *ALine) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "prstDash":
var value APrstDash
value.Val = getAtt(tt.Attr, "val")
l.PrstDash = &value
case "miter":
var value AMiter
value.Limit = getAtt(tt.Attr, "lim")
l.Miter = &value
case "round":
l.Round = &struct{}{}
case "headEnd":
l.HeadEnd = &struct{}{}
l.HeadEnd = new(AHeadEnd)
err = d.DecodeElement(l.HeadEnd, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "tailEnd":
l.TailEnd = &struct{}{}
l.TailEnd = new(ATailEnd)
err = d.DecodeElement(l.TailEnd, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
default:
err = d.Skip() // skip unsupported tags
if err != nil {
@@ -258,6 +285,72 @@ type ASrgbClr struct {
Val string `xml:"val,attr"`
}
// APrstDash ...
type APrstDash struct {
XMLName xml.Name `xml:"a:prstDash,omitempty"`
Val string `xml:"val,attr"`
}
// AMiter ...
type AMiter struct {
XMLName xml.Name `xml:"a:miter,omitempty"`
Limit string `xml:"lim,attr"`
}
// AHeadEnd ...
type AHeadEnd struct {
XMLName xml.Name `xml:"a:headEnd,omitempty"`
Type string `xml:"type,attr,omitempty"`
W string `xml:"w,attr,omitempty"`
Len string `xml:"len,attr,omitempty"`
}
// UnmarshalXML ...
func (r *AHeadEnd) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "type":
r.Type = attr.Value
case "w":
r.W = attr.Value
case "len":
r.Len = attr.Value
default:
// ignore other attributes
}
}
// Consume the end element
_, err := d.Token()
return err
}
// ATailEnd ...
type ATailEnd struct {
XMLName xml.Name `xml:"a:tailEnd,omitempty"`
Type string `xml:"type,attr,omitempty"`
W string `xml:"w,attr,omitempty"`
Len string `xml:"len,attr,omitempty"`
}
// UnmarshalXML ...
func (r *ATailEnd) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "type":
r.Type = attr.Value
case "w":
r.W = attr.Value
case "len":
r.Len = attr.Value
default:
// ignore other attributes
}
}
// Consume the end element
_, err := d.Token()
return err
}
// WPSBodyPr represents the body properties for a WordprocessingML DrawingML shape.
type WPSBodyPr struct {
XMLName xml.Name `xml:"wps:bodyPr,omitempty"`

View File

@@ -19,8 +19,8 @@ func TestShapeStructure(t *testing.T) {
W: 9525,
SolidFill: &ASolidFill{SrgbClr: &ASrgbClr{Val: "000000"}},
Round: &struct{}{},
HeadEnd: &struct{}{},
TailEnd: &struct{}{},
HeadEnd: &AHeadEnd{},
TailEnd: &ATailEnd{},
},
})

View File

@@ -84,6 +84,7 @@ func (f *Docx) parseDocument(file *zip.File) error {
f.Document.XMLWP = XMLNS_WP
// f.Document.XMLMC = XMLNS_MC
f.Document.XMLWPS = XMLNS_WPS
f.Document.XMLWPC = XMLNS_WPC
// f.Document.XMLWP14 = XMLNS_WP14
f.Document.XMLName.Space = XMLNS_W
f.Document.XMLName.Local = "document"