mirror of
https://github.com/fumiama/go-docx.git
synced 2026-06-05 07:40:24 +08:00
refactor: Run use Children
This commit is contained in:
@@ -99,9 +99,11 @@ func (p *Paragraph) AddInlineDrawing(pic []byte) (*Run, error) {
|
||||
},
|
||||
},
|
||||
}
|
||||
c := make([]interface{}, 1, 64)
|
||||
c[0] = d
|
||||
run := &Run{
|
||||
Drawing: d,
|
||||
RunProperties: &RunProperties{},
|
||||
Children: c,
|
||||
}
|
||||
p.Children = append(p.Children, run)
|
||||
return run, nil
|
||||
@@ -207,9 +209,11 @@ func (p *Paragraph) AddAnchorDrawing(pic []byte) (*Run, error) {
|
||||
},
|
||||
},
|
||||
}
|
||||
c := make([]interface{}, 1, 64)
|
||||
c[0] = d
|
||||
run := &Run{
|
||||
Drawing: d,
|
||||
RunProperties: &RunProperties{},
|
||||
Children: c,
|
||||
}
|
||||
p.Children = append(p.Children, run)
|
||||
return run, nil
|
||||
|
||||
@@ -24,8 +24,6 @@ import "unsafe"
|
||||
|
||||
// AddParagraph adds a new paragraph
|
||||
func (f *Docx) AddParagraph() *Paragraph {
|
||||
f.Document.Body.mu.Lock()
|
||||
defer f.Document.Body.mu.Unlock()
|
||||
f.Document.Body.Items = append(f.Document.Body.Items, Paragraph{
|
||||
Children: make([]interface{}, 0, 64),
|
||||
file: f,
|
||||
@@ -38,9 +36,6 @@ func (f *Docx) AddParagraph() *Paragraph {
|
||||
|
||||
// AddParagraph adds a new paragraph
|
||||
func (c *WTableCell) AddParagraph() *Paragraph {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.Paragraphs = append(c.Paragraphs, Paragraph{
|
||||
Children: make([]interface{}, 0, 64),
|
||||
file: c.file,
|
||||
|
||||
14
apirun.go
14
apirun.go
@@ -20,8 +20,6 @@
|
||||
|
||||
package docxlib
|
||||
|
||||
import "encoding/xml"
|
||||
|
||||
// Color allows to set run color
|
||||
func (r *Run) Color(color string) *Run {
|
||||
r.RunProperties.Color = &Color{
|
||||
@@ -42,16 +40,6 @@ func (r *Run) Size(size string) *Run {
|
||||
|
||||
// AddTab add a tab in front of the run
|
||||
func (r *Run) AddTab() *Run {
|
||||
r.FrontTab = append(r.FrontTab, struct {
|
||||
XMLName xml.Name "xml:\"w:tab,omitempty\""
|
||||
}{})
|
||||
return r
|
||||
}
|
||||
|
||||
// AppendTab add a tab after the run
|
||||
func (r *Run) AppendTab() *Run {
|
||||
r.RearTab = append(r.RearTab, struct {
|
||||
XMLName xml.Name "xml:\"w:tab,omitempty\""
|
||||
}{})
|
||||
r.Children = append(r.Children, &WTab{})
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -42,8 +42,6 @@ func (f *Docx) AddTable(row int, col int) *WTable {
|
||||
TableCells: cells,
|
||||
}
|
||||
}
|
||||
f.Document.Body.mu.Lock()
|
||||
defer f.Document.Body.mu.Unlock()
|
||||
f.Document.Body.Items = append(f.Document.Body.Items, WTable{
|
||||
TableProperties: &WTableProperties{
|
||||
Width: &WTableWidth{Type: "auto"},
|
||||
@@ -101,8 +99,6 @@ func (f *Docx) AddTableTwips(rowHeights []int64, colWidths []int64) *WTable {
|
||||
}
|
||||
}
|
||||
}
|
||||
f.Document.Body.mu.Lock()
|
||||
defer f.Document.Body.mu.Unlock()
|
||||
f.Document.Body.Items = append(f.Document.Body.Items, WTable{
|
||||
TableProperties: &WTableProperties{
|
||||
Width: &WTableWidth{Type: "auto"},
|
||||
|
||||
26
apitext.go
26
apitext.go
@@ -20,17 +20,20 @@
|
||||
|
||||
package docxlib
|
||||
|
||||
import "encoding/xml"
|
||||
import "strings"
|
||||
|
||||
// AddTab adds tab to para
|
||||
func (p *Paragraph) AddTab() *Run {
|
||||
c := make([]interface{}, 1, 64)
|
||||
c[0] = &WTab{}
|
||||
|
||||
run := &Run{
|
||||
RunProperties: &RunProperties{},
|
||||
FrontTab: []struct {
|
||||
XMLName xml.Name "xml:\"w:tab,omitempty\""
|
||||
}{{}},
|
||||
Children: c,
|
||||
}
|
||||
|
||||
p.Children = append(p.Children, run)
|
||||
|
||||
return run
|
||||
}
|
||||
|
||||
@@ -40,13 +43,22 @@ func (p *Paragraph) AddText(text string) *Run {
|
||||
return p.AddTab()
|
||||
}
|
||||
|
||||
t := &Text{
|
||||
Text: text,
|
||||
c := make([]interface{}, 0, 64)
|
||||
|
||||
for i, s := range strings.Split(text, "\t") {
|
||||
if i > 0 {
|
||||
c = append(c, &WTab{})
|
||||
}
|
||||
if s != "" {
|
||||
c = append(c, &Text{
|
||||
Text: s,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
run := &Run{
|
||||
Text: t,
|
||||
RunProperties: &RunProperties{},
|
||||
Children: c,
|
||||
}
|
||||
|
||||
p.Children = append(p.Children, run)
|
||||
|
||||
@@ -46,10 +46,10 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
r.Drawing.Anchor.Size(r.Drawing.Anchor.Extent.CX/4, r.Drawing.Anchor.Extent.CY/4)
|
||||
r.Drawing.Anchor.BehindDoc = 1
|
||||
r.Drawing.Anchor.PositionH.PosOffset = r.Drawing.Anchor.Extent.CX
|
||||
r.Drawing.Anchor.Graphic.GraphicData.Pic.BlipFill.Blip.AlphaModFix = &docxlib.AAlphaModFix{Amount: 50000}
|
||||
r.Children[0].(*docxlib.Drawing).Anchor.Size(r.Children[0].(*docxlib.Drawing).Anchor.Extent.CX/4, r.Children[0].(*docxlib.Drawing).Anchor.Extent.CY/4)
|
||||
r.Children[0].(*docxlib.Drawing).Anchor.BehindDoc = 1
|
||||
r.Children[0].(*docxlib.Drawing).Anchor.PositionH.PosOffset = r.Children[0].(*docxlib.Drawing).Anchor.Extent.CX
|
||||
r.Children[0].(*docxlib.Drawing).Anchor.Graphic.GraphicData.Pic.BlipFill.Blip.AlphaModFix = &docxlib.AAlphaModFix{Amount: 50000}
|
||||
// add text
|
||||
para1.AddText("test")
|
||||
para1.AddText("test font size").Size("44")
|
||||
@@ -70,13 +70,13 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
r.Drawing.Inline.Size(r.Drawing.Inline.Extent.CX*4/5, r.Drawing.Inline.Extent.CY*4/5)
|
||||
r.Children[0].(*docxlib.Drawing).Inline.Size(r.Children[0].(*docxlib.Drawing).Inline.Extent.CX*4/5, r.Children[0].(*docxlib.Drawing).Inline.Extent.CY*4/5)
|
||||
para4.AddTab().AddTab()
|
||||
r, err = para4.AddInlineDrawingFrom("testdata/fumiama2x.webp")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
r.Drawing.Inline.Size(r.Drawing.Inline.Extent.CX*4/5, r.Drawing.Inline.Extent.CY*4/5)
|
||||
r.Children[0].(*docxlib.Drawing).Inline.Size(r.Children[0].(*docxlib.Drawing).Inline.Extent.CX*4/5, r.Children[0].(*docxlib.Drawing).Inline.Extent.CY*4/5)
|
||||
|
||||
para5 := w.AddParagraph().Justification("center")
|
||||
// add text
|
||||
|
||||
4
link.go
4
link.go
@@ -66,8 +66,6 @@ func (f *Docx) addImageRelation(m Media) string {
|
||||
|
||||
// ReferTarget gets the target for a reference
|
||||
func (f *Docx) ReferTarget(id string) (string, error) {
|
||||
f.docRelation.mu.RLock()
|
||||
defer f.docRelation.mu.RUnlock()
|
||||
for _, a := range f.docRelation.Relationship {
|
||||
if a.ID == id {
|
||||
return a.Target, nil
|
||||
@@ -78,8 +76,6 @@ func (f *Docx) ReferTarget(id string) (string, error) {
|
||||
|
||||
// ReferID gets the rId from target
|
||||
func (f *Docx) ReferID(target string) (string, error) {
|
||||
f.docRelation.mu.RLock()
|
||||
defer f.docRelation.mu.RUnlock()
|
||||
for _, a := range f.docRelation.Relationship {
|
||||
if a.Target == target {
|
||||
return a.ID, nil
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
"encoding/xml"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//nolint:revive,stylecheck
|
||||
@@ -48,7 +47,6 @@ func getAtt(atts []xml.Attr, name string) string {
|
||||
|
||||
// Body <w:body>
|
||||
type Body struct {
|
||||
mu sync.Mutex
|
||||
Items []interface{}
|
||||
|
||||
file *Docx
|
||||
@@ -74,9 +72,7 @@ func (b *Body) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
return err
|
||||
}
|
||||
value.file = b.file
|
||||
b.mu.Lock()
|
||||
b.Items = append(b.Items, value)
|
||||
b.mu.Unlock()
|
||||
case "tbl":
|
||||
var value WTable
|
||||
err = d.DecodeElement(&value, &tt)
|
||||
@@ -84,9 +80,7 @@ func (b *Body) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
return err
|
||||
}
|
||||
value.file = b.file
|
||||
b.mu.Lock()
|
||||
b.Items = append(b.Items, value)
|
||||
b.mu.Unlock()
|
||||
default:
|
||||
err = d.Skip() // skip unsupported tags
|
||||
if err != nil {
|
||||
|
||||
@@ -38,12 +38,12 @@ func TestDrawingStructure(t *testing.T) {
|
||||
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
|
||||
r.Children[0].(*Drawing).Anchor.Graphic.GraphicData.Pic.BlipFill.Blip.AlphaModFix = &AAlphaModFix{Amount: 50000}
|
||||
r.Children[0].(*Drawing).Anchor.Graphic.GraphicData.Pic.NonVisualPicProperties.CNvPicPr.Locks = &APicLocks{NoChangeAspect: 1}
|
||||
r.Children[0].(*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.AddTab().AddTab().AddTab().AddTab()
|
||||
para2.AddInlineDrawingFrom("testdata/fumiama2x.webp")
|
||||
|
||||
para3 := w.AddParagraph()
|
||||
|
||||
@@ -93,54 +93,58 @@ func (p *Paragraph) String() string {
|
||||
}
|
||||
sb.WriteByte(')')
|
||||
case *Run:
|
||||
switch {
|
||||
case o.Text != nil:
|
||||
sb.WriteString(o.Text.Text)
|
||||
case o.Drawing != nil:
|
||||
if o.Drawing.Inline != nil && o.Drawing.Inline.Graphic != nil && o.Drawing.Inline.Graphic.GraphicData != nil && o.Drawing.Inline.Graphic.GraphicData.Pic != nil {
|
||||
sb.WriteString("
|
||||
if o.Drawing.Inline.Graphic.GraphicData.Pic.BlipFill != nil {
|
||||
tgt, err := p.file.ReferTarget(o.Drawing.Inline.Graphic.GraphicData.Pic.BlipFill.Blip.Embed)
|
||||
if err != nil {
|
||||
sb.WriteString(err.Error())
|
||||
} else {
|
||||
h := md5.Sum(p.file.Media(tgt[6:]).Data)
|
||||
sb.WriteString(hex.EncodeToString(h[:]))
|
||||
for _, c := range o.Children {
|
||||
switch x := c.(type) {
|
||||
case *Text:
|
||||
sb.WriteString(x.Text)
|
||||
case *WTab:
|
||||
sb.WriteByte('\t')
|
||||
case *Drawing:
|
||||
if x.Inline != nil && x.Inline.Graphic != nil && x.Inline.Graphic.GraphicData != nil && x.Inline.Graphic.GraphicData.Pic != nil {
|
||||
sb.WriteString("
|
||||
if o.Drawing.Anchor.Graphic.GraphicData.Pic.BlipFill != nil {
|
||||
tgt, err := p.file.ReferTarget(o.Drawing.Anchor.Graphic.GraphicData.Pic.BlipFill.Blip.Embed)
|
||||
if err != nil {
|
||||
sb.WriteString(err.Error())
|
||||
} else {
|
||||
h := md5.Sum(p.file.Media(tgt[6:]).Data)
|
||||
sb.WriteString(hex.EncodeToString(h[:]))
|
||||
sb.WriteString("](")
|
||||
if x.Inline.Graphic.GraphicData.Pic.BlipFill != nil {
|
||||
tgt, err := p.file.ReferTarget(x.Inline.Graphic.GraphicData.Pic.BlipFill.Blip.Embed)
|
||||
if err != nil {
|
||||
sb.WriteString(err.Error())
|
||||
} else {
|
||||
h := md5.Sum(p.file.Media(tgt[6:]).Data)
|
||||
sb.WriteString(hex.EncodeToString(h[:]))
|
||||
}
|
||||
}
|
||||
sb.WriteByte(')')
|
||||
continue
|
||||
}
|
||||
if x.Anchor != nil && x.Anchor.Graphic != nil && x.Anchor.Graphic.GraphicData != nil && x.Anchor.Graphic.GraphicData.Pic != nil {
|
||||
sb.WriteString("
|
||||
if x.Anchor.Graphic.GraphicData.Pic.BlipFill != nil {
|
||||
tgt, err := p.file.ReferTarget(x.Anchor.Graphic.GraphicData.Pic.BlipFill.Blip.Embed)
|
||||
if err != nil {
|
||||
sb.WriteString(err.Error())
|
||||
} else {
|
||||
h := md5.Sum(p.file.Media(tgt[6:]).Data)
|
||||
sb.WriteString(hex.EncodeToString(h[:]))
|
||||
}
|
||||
}
|
||||
sb.WriteByte(')')
|
||||
}
|
||||
sb.WriteByte(')')
|
||||
}
|
||||
}
|
||||
case *RunProperties:
|
||||
|
||||
@@ -20,10 +20,6 @@
|
||||
|
||||
package docxlib
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
//nolint:revive,stylecheck
|
||||
const (
|
||||
XMLNS_REL = `http://schemas.openxmlformats.org/package/2006/relationships`
|
||||
@@ -35,7 +31,6 @@ const (
|
||||
|
||||
// Relationships ...
|
||||
type Relationships struct {
|
||||
mu sync.RWMutex
|
||||
Xmlns string `xml:"xmlns,attr"`
|
||||
Relationship []Relationship
|
||||
}
|
||||
|
||||
33
structrun.go
33
structrun.go
@@ -29,17 +29,13 @@ import (
|
||||
// Run is part of a paragraph that has its own style. It could be
|
||||
// a piece of text in bold, or a link
|
||||
type Run struct {
|
||||
XMLName xml.Name `xml:"w:r,omitempty"`
|
||||
XMLName xml.Name `xml:"w:r,omitempty"`
|
||||
|
||||
RunProperties *RunProperties `xml:"w:rPr,omitempty"`
|
||||
FrontTab []struct { //TODO: replace with variable []RunChild
|
||||
XMLName xml.Name `xml:"w:tab,omitempty"`
|
||||
}
|
||||
|
||||
InstrText string `xml:"w:instrText,omitempty"`
|
||||
Text *Text
|
||||
Drawing *Drawing
|
||||
RearTab []struct {
|
||||
XMLName xml.Name `xml:"w:tab,omitempty"`
|
||||
}
|
||||
|
||||
Children []interface{}
|
||||
}
|
||||
|
||||
// UnmarshalXML ...
|
||||
@@ -53,6 +49,8 @@ func (r *Run) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var child interface{}
|
||||
|
||||
if tt, ok := t.(xml.StartElement); ok {
|
||||
switch tt.Name.Local {
|
||||
case "rPr":
|
||||
@@ -62,6 +60,7 @@ func (r *Run) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
return err
|
||||
}
|
||||
r.RunProperties = &value
|
||||
continue
|
||||
case "instrText":
|
||||
var value string
|
||||
err = d.DecodeElement(&value, &tt)
|
||||
@@ -69,30 +68,23 @@ func (r *Run) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
return err
|
||||
}
|
||||
r.InstrText = value
|
||||
continue
|
||||
case "t":
|
||||
var value Text
|
||||
err = d.DecodeElement(&value, &tt)
|
||||
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
|
||||
return err
|
||||
}
|
||||
r.Text = &value
|
||||
child = &value
|
||||
case "drawing":
|
||||
var value Drawing
|
||||
err = d.DecodeElement(&value, &tt)
|
||||
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
|
||||
return err
|
||||
}
|
||||
r.Drawing = &value
|
||||
child = &value
|
||||
case "tab":
|
||||
if r.InstrText == "" && r.Text == nil && r.Drawing == nil {
|
||||
r.FrontTab = append(r.FrontTab, struct {
|
||||
XMLName xml.Name "xml:\"w:tab,omitempty\""
|
||||
}{})
|
||||
} else {
|
||||
r.RearTab = append(r.RearTab, struct {
|
||||
XMLName xml.Name "xml:\"w:tab,omitempty\""
|
||||
}{})
|
||||
}
|
||||
child = &WTab{}
|
||||
default:
|
||||
err = d.Skip() // skip unsupported tags
|
||||
if err != nil {
|
||||
@@ -100,6 +92,7 @@ func (r *Run) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
r.Children = append(r.Children, child)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// WTable represents a table within a Word document.
|
||||
@@ -502,8 +501,6 @@ type WTableRowHeight struct {
|
||||
|
||||
// WTableCell represents a cell within a table.
|
||||
type WTableCell struct {
|
||||
mu sync.Mutex
|
||||
|
||||
XMLName xml.Name `xml:"w:tc,omitempty"`
|
||||
TableCellProperties *WTableCellProperties
|
||||
Paragraphs []Paragraph `xml:"w:p,omitempty"`
|
||||
@@ -532,9 +529,7 @@ func (c *WTableCell) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
|
||||
}
|
||||
if len(value.Children) > 0 {
|
||||
value.file = c.file
|
||||
c.mu.Lock()
|
||||
c.Paragraphs = append(c.Paragraphs, value)
|
||||
c.mu.Unlock()
|
||||
}
|
||||
case "tcPr":
|
||||
var value WTableCellProperties
|
||||
|
||||
@@ -41,9 +41,9 @@ func TestTableStructure(t *testing.T) {
|
||||
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
|
||||
r.Children[0].(*Drawing).Anchor.Graphic.GraphicData.Pic.BlipFill.Blip.AlphaModFix = &AAlphaModFix{Amount: 50000}
|
||||
r.Children[0].(*Drawing).Anchor.Graphic.GraphicData.Pic.NonVisualPicProperties.CNvPicPr.Locks = &APicLocks{NoChangeAspect: 1}
|
||||
r.Children[0].(*Drawing).Anchor.Graphic.GraphicData.Pic.SpPr.Xfrm.Rot = 50000
|
||||
para3 := tab1.TableRows[0].TableCells[0].AddParagraph()
|
||||
para3.AddText("first cell")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user