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

feat: add shade effect

This commit is contained in:
源文雨
2023-02-26 15:01:17 +08:00
parent 592c7b5d13
commit 0e18f8a163
11 changed files with 154 additions and 80 deletions

View File

@@ -25,7 +25,6 @@ func (r *Run) Color(color string) *Run {
r.RunProperties.Color = &Color{
Val: color,
}
return r
}
@@ -34,7 +33,16 @@ func (r *Run) Size(size string) *Run {
r.RunProperties.Size = &Size{
Val: size,
}
return r
}
// Shade allows to set run shade
func (r *Run) Shade(val, color, fill string) *Run {
r.RunProperties.Shade = &Shade{
Val: val,
Color: color,
Fill: fill,
}
return r
}

View File

@@ -158,3 +158,13 @@ func (w *WTableRow) Justification(val string) *WTableRow {
w.TableRowProperties.Justification.Val = val
return w
}
// Shade allows to set cell's shade
func (c *WTableCell) Shade(val, color, fill string) *WTableCell {
c.TableCellProperties.Shade = &Shade{
Val: val,
Color: color,
Fill: fill,
}
return c
}

View File

@@ -51,9 +51,10 @@ func main() {
r.Children[0].(*docx.Drawing).Anchor.PositionH.PosOffset = r.Children[0].(*docx.Drawing).Anchor.Extent.CX
r.Children[0].(*docx.Drawing).Anchor.Graphic.GraphicData.Pic.BlipFill.Blip.AlphaModFix = &docx.AAlphaModFix{Amount: 50000}
// add text
para1.AddText("test")
para1.AddText("test font size").Size("44")
para1.AddText("test color").Color("808080")
para1.AddText("test").AddTab()
para1.AddText("test font size").Size("44").AddTab()
para1.AddText("test color").Color("808080").AddTab()
para1.AddText("test shade").Shade("clear", "auto", "E7E6E6").AddTab()
para2 := w.AddParagraph().Justification("end")
para2.AddText("test font size and color").Size("44").Color("ff0000")
@@ -88,10 +89,16 @@ func main() {
panic(err)
}
tbl1 := w.AddTable(3, 2)
w.AddParagraph()
tbl1 := w.AddTable(9, 9)
for x, r := range tbl1.TableRows {
red := (x + 1) * 28
for y, c := range r.TableCells {
c.AddParagraph().AddText(fmt.Sprintf("(%d, %d)", x, y))
green := ((y + 1) / 3) * 85
blue := (y%3 + 1) * 85
v := fmt.Sprintf("%02X%02X%02X", red, green, blue)
c.Shade("clear", "auto", v).AddParagraph().AddText(v).Size("18")
}
}
@@ -105,6 +112,7 @@ func main() {
c.AddParagraph().Justification("center").AddText(fmt.Sprintf("(%d, %d)", x, y))
}
}
tbl2.TableRows[0].TableCells[0].Shade("clear", "auto", "E7E6E6")
f, err := os.Create(*fileLocation)
if err != nil {

View File

@@ -236,10 +236,7 @@ func (r *WPExtent) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
}
// Consume the end element
_, err = d.Token()
if err != nil {
return err
}
return nil
return err
}
// WPEffectExtent represents the effect extent of a drawing in a Word document.
@@ -280,10 +277,7 @@ func (r *WPEffectExtent) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
}
// Consume the end element
_, err = d.Token()
if err != nil {
return err
}
return nil
return err
}
// WPDocPr represents the document properties of a drawing in a Word document.
@@ -312,10 +306,7 @@ func (r *WPDocPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
}
// Consume the end element
_, err := d.Token()
if err != nil {
return err
}
return nil
return err
}
// WPCNvGraphicFramePr represents the non-visual properties of a graphic frame.

View File

@@ -33,7 +33,7 @@ func TestDrawingStructure(t *testing.T) {
// add new paragraph
para1 := w.AddParagraph()
// add text
para1.AddText("直接粘贴 inline").AddTab()
para1.AddText("直接粘贴 inline").Shade("clear", "auto", "E7E6E6").AddTab()
r, err := para1.AddAnchorDrawingFrom("testdata/fumiama.JPG")
if err != nil {
t.Fatal(err)

74
structeffects.go Normal file
View File

@@ -0,0 +1,74 @@
package docx
import "encoding/xml"
// RunStyle contains styling for a run
type RunStyle struct {
XMLName xml.Name `xml:"w:rStyle,omitempty"`
Val string `xml:"w:val,attr"`
}
// Style contains styling for a paragraph
type Style struct {
XMLName xml.Name `xml:"w:pStyle,omitempty"`
Val string `xml:"w:val,attr"`
}
// Color contains the sound of music. :D
// I'm kidding. It contains the color
type Color struct {
XMLName xml.Name `xml:"w:color,omitempty"`
Val string `xml:"w:val,attr"`
}
// Size contains the font size
type Size struct {
XMLName xml.Name `xml:"w:sz,omitempty"`
Val string `xml:"w:val,attr"`
}
// Justification contains the way of the horizonal alignment
//
// w:jc 属性的取值可以是以下之一:
// start左对齐。
// center居中对齐。
// end右对齐。
// both两端对齐。
// distribute分散对齐。
type Justification struct {
XMLName xml.Name `xml:"w:jc,omitempty"`
Val string `xml:"w:val,attr"`
}
// Shade is an element that represents a shading pattern applied to a document element.
type Shade struct {
XMLName xml.Name `xml:"w:shd,omitempty"`
Val string `xml:"w:val,attr,omitempty"`
Color string `xml:"w:color,attr,omitempty"`
Fill string `xml:"w:fill,attr,omitempty"`
ThemeFill string `xml:"w:themeFill,attr,omitempty"`
ThemeFillTint string `xml:"w:themeFillTint,attr,omitempty"`
}
// UnmarshalXML ...
func (s *Shade) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "val":
s.Val = attr.Value
case "color":
s.Color = attr.Value
case "fill":
s.Fill = attr.Value
case "themeFill":
s.ThemeFill = attr.Value
case "themeFillTint":
s.ThemeFillTint = attr.Value
default:
// ignore other attributes
}
}
// Consume the end element
_, err := d.Token()
return err
}

View File

@@ -30,8 +30,9 @@ import (
// ParagraphProperties <w:pPr>
type ParagraphProperties struct {
XMLName xml.Name `xml:"w:pPr,omitempty"`
Justification *Justification `xml:"w:jc,omitempty"`
XMLName xml.Name `xml:"w:pPr,omitempty"`
Justification *Justification
Shade *Shade
}
// UnmarshalXML ...
@@ -48,6 +49,13 @@ func (p *ParagraphProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElemen
switch tt.Name.Local {
case "jc":
p.Justification = &Justification{Val: getAtt(tt.Attr, "val")}
case "shd":
var value Shade
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
p.Shade = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {

View File

@@ -106,11 +106,12 @@ type WTab struct {
// RunProperties encapsulates visual properties of a run
type RunProperties struct {
XMLName xml.Name `xml:"w:rPr,omitempty"`
Color *Color `xml:"w:color,omitempty"`
Size *Size `xml:"w:sz,omitempty"`
RunStyle *RunStyle `xml:"w:rStyle,omitempty"`
Style *Style `xml:"w:pStyle,omitempty"`
XMLName xml.Name `xml:"w:rPr,omitempty"`
Color *Color
Size *Size
RunStyle *RunStyle
Style *Style
Shade *Shade
}
// UnmarshalXML ...
@@ -142,6 +143,13 @@ func (r *RunProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
var value Style
value.Val = getAtt(tt.Attr, "val")
r.Style = &value
case "shd":
var value Shade
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.Shade = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {
@@ -154,41 +162,3 @@ func (r *RunProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
return nil
}
// RunStyle contains styling for a run
type RunStyle struct {
XMLName xml.Name `xml:"w:rStyle,omitempty"`
Val string `xml:"w:val,attr"`
}
// Style contains styling for a paragraph
type Style struct {
XMLName xml.Name `xml:"w:pStyle,omitempty"`
Val string `xml:"w:val,attr"`
}
// Color contains the sound of music. :D
// I'm kidding. It contains the color
type Color struct {
XMLName xml.Name `xml:"w:color"`
Val string `xml:"w:val,attr"`
}
// Size contains the font size
type Size struct {
XMLName xml.Name `xml:"w:sz"`
Val string `xml:"w:val,attr"`
}
// Justification contains the way of the horizonal alignment
//
// w:jc 属性的取值可以是以下之一:
// start左对齐。
// center居中对齐。
// end右对齐。
// both两端对齐。
// distribute分散对齐。
type Justification struct {
// XMLName xml.Name `xml:"w:jc"`
Val string `xml:"w:val,attr"`
}

View File

@@ -307,10 +307,7 @@ func (t *WTableLook) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
}
// Consume the end element
_, err := d.Token()
if err != nil {
return err
}
return nil
return err
}
// WTableGrid is a structure that represents the table grid of a Word document.
@@ -382,6 +379,7 @@ func (g *WGridCol) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err err
type WTableRow struct {
XMLName xml.Name `xml:"w:tr,omitempty"`
RsidR string `xml:"w:rsidR,attr,omitempty"`
RsidRPr string `xml:"w:rsidRPr,attr,omitempty"`
RsidTr string `xml:"w:rsidTr,attr,omitempty"`
TableRowProperties *WTableRowProperties
TableCells []*WTableCell
@@ -395,6 +393,8 @@ func (w *WTableRow) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch attr.Name.Local {
case "rsidR":
w.RsidR = attr.Value
case "rsidRPr":
w.RsidRPr = attr.Value
case "rsidTr":
w.RsidTr = attr.Value
default:
@@ -443,7 +443,7 @@ func (w *WTableRow) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
type WTableRowProperties struct {
XMLName xml.Name `xml:"w:trPr,omitempty"`
TableRowHeight *WTableRowHeight
Justification *Justification `xml:"w:jc,omitempty"`
Justification *Justification
}
// UnmarshalXML ...
@@ -462,12 +462,14 @@ func (t *WTableRowProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElemen
case "trHeight":
th := new(WTableRowHeight)
for _, attr := range tt.Attr {
if attr.Name.Local == "val" {
switch attr.Name.Local {
case "val":
th.Val, err = strconv.ParseInt(attr.Value, 10, 64)
if err != nil {
return err
}
break
case "hRule":
th.Rule = attr.Value
}
}
t.TableRowHeight = th
@@ -502,6 +504,7 @@ func (t *WTableRowProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElemen
// WTableRowHeight represents the height of a row within a table.
type WTableRowHeight struct {
XMLName xml.Name `xml:"w:trHeight,omitempty"`
Rule string `xml:"w:hRule,omitempty"`
Val int64 `xml:"w:val,attr"`
}
@@ -563,6 +566,7 @@ type WTableCellProperties struct {
GridSpan *WGridSpan
VAlign *WVerticalAlignment
TableBorders *WTableBorders `xml:"w:tcBorders"`
Shade *Shade
}
// UnmarshalXML ...
@@ -608,6 +612,13 @@ func (r *WTableCellProperties) UnmarshalXML(d *xml.Decoder, start xml.StartEleme
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "shd":
var value Shade
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.Shade = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {
@@ -743,10 +754,7 @@ func (t *WTableBorder) UnmarshalXML(d *xml.Decoder, start xml.StartElement) erro
}
// Consume the end element
_, err := d.Token()
if err != nil {
return err
}
return nil
return err
}
// WGridSpan represents the number of grid columns this cell should span.

View File

@@ -36,7 +36,7 @@ func TestTableStructure(t *testing.T) {
para1.AddText("table")
tab1 := w.AddTable(4, 3).Justification("center")
tab1.TableProperties.Position = &WTablePositioningProperties{LeftFromText: 2333}
para2 := tab1.TableRows[3].Justification("center").TableCells[2].AddParagraph()
para2 := tab1.TableRows[3].Justification("center").TableCells[2].Shade("clear", "auto", "E7E6E6").AddParagraph()
r, err := para2.AddAnchorDrawingFrom("testdata/fumiama.JPG")
if err != nil {
t.Fatal(err)

View File

@@ -87,10 +87,7 @@ func (f *Docx) parseDocument(file *zip.File) error {
f.Document.Body.file = f
err = xml.NewDecoder(zf).Decode(&f.Document)
if err != nil {
return err
}
return nil
return err
}
// parseDocRelation processes one of the relevant files, the one with the relationships