mirror of
https://github.com/fumiama/go-docx.git
synced 2026-06-20 01:20:32 +08:00
add: wpc & more w:ln
This commit is contained in:
@@ -130,8 +130,8 @@ func main() {
|
|||||||
W: 9525,
|
W: 9525,
|
||||||
SolidFill: &docx.ASolidFill{SrgbClr: &docx.ASrgbClr{Val: "000000"}},
|
SolidFill: &docx.ASolidFill{SrgbClr: &docx.ASrgbClr{Val: "000000"}},
|
||||||
Round: &struct{}{},
|
Round: &struct{}{},
|
||||||
HeadEnd: &struct{}{},
|
HeadEnd: &docx.AHeadEnd{},
|
||||||
TailEnd: &struct{}{},
|
TailEnd: &docx.ATailEnd{},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
1
empty.go
1
empty.go
@@ -35,6 +35,7 @@ func newEmptyA4File() *Docx {
|
|||||||
XMLR: XMLNS_R,
|
XMLR: XMLNS_R,
|
||||||
XMLWP: XMLNS_WP,
|
XMLWP: XMLNS_WP,
|
||||||
XMLWPS: XMLNS_WPS,
|
XMLWPS: XMLNS_WPS,
|
||||||
|
XMLWPC: XMLNS_WPC,
|
||||||
// XMLMC: XMLNS_MC,
|
// XMLMC: XMLNS_MC,
|
||||||
// XMLWP14: XMLNS_WP14,
|
// XMLWP14: XMLNS_WP14,
|
||||||
Body: Body{
|
Body: Body{
|
||||||
|
|||||||
2
id.go
2
id.go
@@ -2,7 +2,7 @@ package docx
|
|||||||
|
|
||||||
func (f *Docx) IncreaseID(name string) (n uintptr) {
|
func (f *Docx) IncreaseID(name string) (n uintptr) {
|
||||||
f.slowIDsMu.Lock()
|
f.slowIDsMu.Lock()
|
||||||
n, _ = f.slowIDs[name] //nolint: go-staticcheck
|
n = f.slowIDs[name]
|
||||||
n++
|
n++
|
||||||
f.slowIDs[name] = n
|
f.slowIDs[name] = n
|
||||||
f.slowIDsMu.Unlock()
|
f.slowIDsMu.Unlock()
|
||||||
|
|||||||
127
structcanvas.go
Normal file
127
structcanvas.go
Normal 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
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ const (
|
|||||||
XMLNS_R = `http://schemas.openxmlformats.org/officeDocument/2006/relationships`
|
XMLNS_R = `http://schemas.openxmlformats.org/officeDocument/2006/relationships`
|
||||||
XMLNS_WP = `http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing`
|
XMLNS_WP = `http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing`
|
||||||
XMLNS_WPS = `http://schemas.microsoft.com/office/word/2010/wordprocessingShape`
|
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_MC = `http://schemas.openxmlformats.org/markup-compatibility/2006`
|
||||||
// XMLNS_WP14 = `http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing`
|
// 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
|
XMLR string `xml:"xmlns:r,attr,omitempty"` // cannot be unmarshalled in
|
||||||
XMLWP string `xml:"xmlns:wp,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
|
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
|
// XMLMC string `xml:"xmlns:mc,attr,omitempty"` // cannot be unmarshalled in
|
||||||
// XMLWP14 string `xml:"xmlns:wp14,attr,omitempty"` // cannot be unmarshalled in
|
// XMLWP14 string `xml:"xmlns:wp14,attr,omitempty"` // cannot be unmarshalled in
|
||||||
|
|
||||||
|
|||||||
105
structshape.go
105
structshape.go
@@ -152,13 +152,18 @@ func (w *WPSSpPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|||||||
|
|
||||||
// ALine represents a line element in a Word document.
|
// ALine represents a line element in a Word document.
|
||||||
type ALine struct {
|
type ALine struct {
|
||||||
XMLName xml.Name `xml:"a:ln,omitempty"`
|
XMLName xml.Name `xml:"a:ln,omitempty"`
|
||||||
W int64 `xml:"w,attr"`
|
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
|
SolidFill *ASolidFill
|
||||||
|
PrstDash *APrstDash
|
||||||
|
Miter *AMiter
|
||||||
Round *struct{} `xml:"a:round,omitempty"`
|
Round *struct{} `xml:"a:round,omitempty"`
|
||||||
HeadEnd *struct{} `xml:"a:headEnd,omitempty"`
|
HeadEnd *AHeadEnd
|
||||||
TailEnd *struct{} `xml:"a:tailEnd,omitempty"`
|
TailEnd *ATailEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalXML ...
|
// UnmarshalXML ...
|
||||||
@@ -170,6 +175,12 @@ func (l *ALine) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case "cap":
|
||||||
|
l.Cap = attr.Value
|
||||||
|
case "cmpd":
|
||||||
|
l.Compound = attr.Value
|
||||||
|
case "algn":
|
||||||
|
l.Align = attr.Value
|
||||||
default:
|
default:
|
||||||
// ignore other attributes
|
// 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") {
|
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
|
||||||
return err
|
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":
|
case "round":
|
||||||
l.Round = &struct{}{}
|
l.Round = &struct{}{}
|
||||||
case "headEnd":
|
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":
|
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:
|
default:
|
||||||
err = d.Skip() // skip unsupported tags
|
err = d.Skip() // skip unsupported tags
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -258,6 +285,72 @@ type ASrgbClr struct {
|
|||||||
Val string `xml:"val,attr"`
|
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.
|
// WPSBodyPr represents the body properties for a WordprocessingML DrawingML shape.
|
||||||
type WPSBodyPr struct {
|
type WPSBodyPr struct {
|
||||||
XMLName xml.Name `xml:"wps:bodyPr,omitempty"`
|
XMLName xml.Name `xml:"wps:bodyPr,omitempty"`
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ func TestShapeStructure(t *testing.T) {
|
|||||||
W: 9525,
|
W: 9525,
|
||||||
SolidFill: &ASolidFill{SrgbClr: &ASrgbClr{Val: "000000"}},
|
SolidFill: &ASolidFill{SrgbClr: &ASrgbClr{Val: "000000"}},
|
||||||
Round: &struct{}{},
|
Round: &struct{}{},
|
||||||
HeadEnd: &struct{}{},
|
HeadEnd: &AHeadEnd{},
|
||||||
TailEnd: &struct{}{},
|
TailEnd: &ATailEnd{},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ func (f *Docx) parseDocument(file *zip.File) error {
|
|||||||
f.Document.XMLWP = XMLNS_WP
|
f.Document.XMLWP = XMLNS_WP
|
||||||
// f.Document.XMLMC = XMLNS_MC
|
// f.Document.XMLMC = XMLNS_MC
|
||||||
f.Document.XMLWPS = XMLNS_WPS
|
f.Document.XMLWPS = XMLNS_WPS
|
||||||
|
f.Document.XMLWPC = XMLNS_WPC
|
||||||
// f.Document.XMLWP14 = XMLNS_WP14
|
// f.Document.XMLWP14 = XMLNS_WP14
|
||||||
f.Document.XMLName.Space = XMLNS_W
|
f.Document.XMLName.Space = XMLNS_W
|
||||||
f.Document.XMLName.Local = "document"
|
f.Document.XMLName.Local = "document"
|
||||||
|
|||||||
Reference in New Issue
Block a user