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

优化完善 table canvas

This commit is contained in:
源文雨
2023-03-02 18:07:53 +08:00
parent fa6f03aaff
commit 64b3464cbf
17 changed files with 806 additions and 156 deletions

View File

@@ -69,7 +69,7 @@ func (p *Paragraph) AddInlineDrawing(pic []byte) (*Run, error) {
XMLA: XMLNS_DRAWINGML_MAIN,
GraphicData: &AGraphicData{
URI: XMLNS_PICTURE,
Pic: &PICPic{
Pic: &Picture{
XMLPIC: XMLNS_DRAWINGML_PICTURE,
NonVisualPicProperties: &PICNonVisualPicProperties{
NonVisualDrawingProperties: PICNonVisualDrawingProperties{
@@ -179,7 +179,7 @@ func (p *Paragraph) AddAnchorDrawing(pic []byte) (*Run, error) {
XMLA: XMLNS_DRAWINGML_MAIN,
GraphicData: &AGraphicData{
URI: XMLNS_PICTURE,
Pic: &PICPic{
Pic: &Picture{
XMLPIC: XMLNS_DRAWINGML_PICTURE,
NonVisualPicProperties: &PICNonVisualPicProperties{
NonVisualDrawingProperties: PICNonVisualDrawingProperties{

View File

@@ -1,3 +1,23 @@
/*
Copyright (c) 2020 gingfrederik
Copyright (c) 2021 Gonzalo Fernandez-Victorio
Copyright (c) 2021 Basement Crowd Ltd (https://www.basementcrowd.com)
Copyright (c) 2023 Fumiama Minamoto (源文雨)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package docx
import (
@@ -5,8 +25,63 @@ import (
"sync/atomic"
)
// AddShape adds wsp named drawing to paragraph
func (p *Paragraph) AddShape(w, h int64, name, bwMode, prst string, elems []interface{}) (*Run, error) {
// AddInlineShape adds wsp named drawing to paragraph
func (p *Paragraph) AddInlineShape(w, h int64, name, bwMode, prst string, ln *ALine) (*Run, error) {
idn := int(atomic.AddUintptr(&p.file.docID, 1))
id := strconv.Itoa(int(p.file.IncreaseID(name)))
d := &Drawing{
Inline: &WPInline{
Extent: &WPExtent{
CX: w,
CY: h,
},
EffectExtent: &WPEffectExtent{},
DocPr: &WPDocPr{
ID: idn,
Name: name + " " + id,
},
CNvGraphicFramePr: &WPCNvGraphicFramePr{},
Graphic: &AGraphic{
XMLA: XMLNS_DRAWINGML_MAIN,
GraphicData: &AGraphicData{
URI: XMLNS_WPS,
Shape: &WordprocessingShape{
CNvCnPr: &WPSCNvCnPr{
ConnShapeLocks: &struct{}{},
},
SpPr: &WPSSpPr{
BWMode: bwMode,
Xfrm: AXfrm{
Ext: AExt{
CX: w,
CY: h,
},
},
PrstGeom: APrstGeom{
Prst: prst,
},
NoFill: &struct{}{},
Line: ln,
},
BodyPr: &WPSBodyPr{},
},
},
},
},
}
c := make([]interface{}, 1, 64)
c[0] = d
run := &Run{
RunProperties: &RunProperties{},
Children: c,
}
p.Children = append(p.Children, run)
return run, nil
}
// AddAnchorShape adds wsp named drawing to paragraph
func (p *Paragraph) AddAnchorShape(w, h int64, name, bwMode, prst string, ln *ALine) (*Run, error) {
idn := int(atomic.AddUintptr(&p.file.docID, 1))
id := strconv.Itoa(int(p.file.IncreaseID(name)))
d := &Drawing{
@@ -37,7 +112,7 @@ func (p *Paragraph) AddShape(w, h int64, name, bwMode, prst string, elems []inte
XMLA: XMLNS_DRAWINGML_MAIN,
GraphicData: &AGraphicData{
URI: XMLNS_WPS,
Shape: &WPSWordprocessingShape{
Shape: &WordprocessingShape{
CNvCnPr: &WPSCNvCnPr{
ConnShapeLocks: &struct{}{},
},
@@ -54,7 +129,7 @@ func (p *Paragraph) AddShape(w, h int64, name, bwMode, prst string, elems []inte
Prst: prst,
},
NoFill: &struct{}{},
Elems: elems,
Line: ln,
},
BodyPr: &WPSBodyPr{},
},

View File

@@ -125,7 +125,7 @@ func main() {
p := w.AddParagraph().Justification("center")
p.AddText("测试 AutoShape w:ln").Size("44")
p.AddShape(808355, 238760, "AutoShape", "auto", "straightConnector1", []interface{}{
p.AddAnchorShape(808355, 238760, "AutoShape", "auto", "straightConnector1",
&docx.ALine{
W: 9525,
SolidFill: &docx.ASolidFill{SrgbClr: &docx.ASrgbClr{Val: "000000"}},
@@ -133,7 +133,16 @@ func main() {
HeadEnd: &docx.AHeadEnd{},
TailEnd: &docx.ATailEnd{},
},
})
)
p.AddInlineShape(808355, 238760, "AutoShape", "auto", "straightConnector1",
&docx.ALine{
W: 9525,
SolidFill: &docx.ASolidFill{SrgbClr: &docx.ASrgbClr{Val: "000000"}},
Round: &struct{}{},
HeadEnd: &docx.AHeadEnd{},
TailEnd: &docx.ATailEnd{},
},
)
f, err := os.Create(*fileLocation)
if err != nil {
@@ -193,7 +202,7 @@ func main() {
if len(c.Paragraphs) > 0 && len(c.Paragraphs[0].Children) > 0 {
fmt.Printf("<%d> %v\t", y, &c.Paragraphs[0])
} else {
fmt.Print("\t")
fmt.Printf("<%d> \t\t", y)
}
}
fmt.Print("\n")

View File

@@ -60,21 +60,11 @@ func newEmptyA4File() *Docx {
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",
},
},
},
media: make([]Media, 0, 64),
mediaNameIdx: make(map[string]int, 64),
rID: 5,
rID: 3,
slowIDs: make(map[string]uintptr, 64),
template: "a4",
tmpfslst: []string{
@@ -83,9 +73,7 @@ func newEmptyA4File() *Docx {
"docProps/core.xml",
"word/theme/theme1.xml",
"word/fontTable.xml",
"word/settings.xml",
"word/styles.xml",
"word/webSettings.xml",
"[Content_Types].xml",
},
buf: bytes.NewBuffer(make([]byte, 0, 1024*1024)),

20
id.go
View File

@@ -1,3 +1,23 @@
/*
Copyright (c) 2020 gingfrederik
Copyright (c) 2021 Gonzalo Fernandez-Victorio
Copyright (c) 2021 Basement Crowd Ltd (https://www.basementcrowd.com)
Copyright (c) 2023 Fumiama Minamoto (源文雨)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package docx
func (f *Docx) IncreaseID(name string) (n uintptr) {

View File

@@ -1,3 +1,23 @@
/*
Copyright (c) 2020 gingfrederik
Copyright (c) 2021 Gonzalo Fernandez-Victorio
Copyright (c) 2021 Basement Crowd Ltd (https://www.basementcrowd.com)
Copyright (c) 2023 Fumiama Minamoto (源文雨)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package docx
import (
@@ -12,6 +32,8 @@ type WordprocessingCanvas struct {
Whole *WPCWhole
Items []interface{}
file *Docx
}
// UnmarshalXML ...
@@ -40,7 +62,8 @@ func (c *WordprocessingCanvas) UnmarshalXML(d *xml.Decoder, start xml.StartEleme
return err
}
case "wsp":
var value WPSWordprocessingShape
var value WordprocessingShape
value.file = c.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err

View File

@@ -44,6 +44,8 @@ type Drawing struct {
XMLName xml.Name `xml:"w:drawing,omitempty"`
Inline *WPInline
Anchor *WPAnchor
file *Docx
}
// UnmarshalXML ...
@@ -61,12 +63,14 @@ func (r *Drawing) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch tt.Name.Local {
case "inline":
r.Inline = new(WPInline)
r.Inline.file = r.file
err = d.DecodeElement(r.Inline, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "anchor":
r.Anchor = new(WPAnchor)
r.Anchor.file = r.file
err = d.DecodeElement(r.Anchor, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
@@ -105,6 +109,8 @@ type WPInline struct {
DocPr *WPDocPr
CNvGraphicFramePr *WPCNvGraphicFramePr
Graphic *AGraphic
file *Docx
}
// UnmarshalXML ...
@@ -191,6 +197,7 @@ func (r *WPInline) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err err
r.CNvGraphicFramePr = &value
case "graphic":
var value AGraphic
value.file = r.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
@@ -360,6 +367,8 @@ type AGraphic struct {
XMLName xml.Name `xml:"a:graphic,omitempty"`
XMLA string `xml:"xmlns:a,attr,omitempty"`
GraphicData *AGraphicData
file *Docx
}
// UnmarshalXML ...
@@ -385,6 +394,7 @@ func (a *AGraphic) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch tt.Name.Local {
case "graphicData":
var value AGraphicData
value.file = a.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
@@ -407,8 +417,11 @@ func (a *AGraphic) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
type AGraphicData struct {
XMLName xml.Name `xml:"a:graphicData,omitempty"`
URI string `xml:"uri,attr"`
Pic *PICPic
Shape *WPSWordprocessingShape
Pic *Picture
Shape *WordprocessingShape
Canvas *WordprocessingCanvas
file *Docx
}
// UnmarshalXML ...
@@ -425,7 +438,7 @@ func (a *AGraphicData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) erro
if tt, ok := t.(xml.StartElement); ok {
switch tt.Name.Local {
case "pic":
var value PICPic
var value Picture
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
@@ -433,12 +446,21 @@ func (a *AGraphicData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) erro
value.XMLPIC = getAtt(tt.Attr, "pic")
a.Pic = &value
case "wsp":
var value WPSWordprocessingShape
var value WordprocessingShape
value.file = a.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
a.Shape = &value
case "wpc":
var value WordprocessingCanvas
value.file = a.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
a.Canvas = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {
@@ -451,8 +473,8 @@ func (a *AGraphicData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) erro
return nil
}
// PICPic represents a picture in a Word document.
type PICPic struct {
// Picture represents a picture in a Word document.
type Picture struct {
XMLName xml.Name `xml:"pic:pic,omitempty"`
XMLPIC string `xml:"xmlns:pic,attr,omitempty"`
NonVisualPicProperties *PICNonVisualPicProperties
@@ -461,7 +483,7 @@ type PICPic struct {
}
// UnmarshalXML ...
func (p *PICPic) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
func (p *Picture) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err == io.EOF {
@@ -649,7 +671,7 @@ func (p *PICBlipFill) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
type ABlip struct {
XMLName xml.Name `xml:"a:blip,omitempty"`
Embed string `xml:"r:embed,attr"`
Cstate string `xml:"cstate,attr"`
Cstate string `xml:"cstate,attr,omitempty"`
AlphaModFix *AAlphaModFix
}
@@ -934,6 +956,8 @@ type WPAnchor struct {
DocPr *WPDocPr
CNvGraphicFramePr *WPCNvGraphicFramePr
Graphic *AGraphic
file *Docx
}
// UnmarshalXML ...
@@ -1061,6 +1085,7 @@ func (r *WPAnchor) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err err
}
case "graphic":
r.Graphic = new(AGraphic)
r.Graphic.file = r.file
err = d.DecodeElement(&r.Graphic, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err

View File

@@ -1,3 +1,23 @@
/*
Copyright (c) 2020 gingfrederik
Copyright (c) 2021 Gonzalo Fernandez-Victorio
Copyright (c) 2021 Basement Crowd Ltd (https://www.basementcrowd.com)
Copyright (c) 2023 Fumiama Minamoto (源文雨)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package docx
import "encoding/xml"
@@ -27,6 +47,12 @@ type Size struct {
Val string `xml:"w:val,attr"`
}
// SizeCs contains the cs font size
type SizeCs struct {
XMLName xml.Name `xml:"w:szCs,omitempty"`
Val string `xml:"w:val,attr"`
}
// Bold ...
type Bold struct {
XMLName xml.Name `xml:"w:b,omitempty"`
@@ -52,7 +78,7 @@ type Highlight struct {
// Kern ...
type Kern struct {
XMLName xml.Name `xml:"w:kern,omitempty"`
Val int64 `xml:"w:val,attr,omitempty"`
Val int64 `xml:"w:val,attr"`
}
// Justification contains the way of the horizonal alignment
@@ -68,6 +94,18 @@ type Justification struct {
Val string `xml:"w:val,attr"`
}
// TextAlignment ...
type TextAlignment struct {
XMLName xml.Name `xml:"w:textAlignment,omitempty"`
Val string `xml:"w:val,attr"`
}
// VertAlign ...
type VertAlign struct {
XMLName xml.Name `xml:"w:vertAlign,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"`
@@ -100,3 +138,27 @@ func (s *Shade) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
_, err := d.Token()
return err
}
// AdjustRightInd ...
type AdjustRightInd struct {
XMLName xml.Name `xml:"w:adjustRightInd,omitempty"`
Val int `xml:"w:val,attr"`
}
// SnapToGrid ...
type SnapToGrid struct {
XMLName xml.Name `xml:"w:snapToGrid,omitempty"`
Val int `xml:"w:val,attr"`
}
// Kinsoku ...
type Kinsoku struct {
XMLName xml.Name `xml:"w:kinsoku,omitempty"`
Val int `xml:"w:val,attr"`
}
// OverflowPunct ...
type OverflowPunct struct {
XMLName xml.Name `xml:"w:overflowPunct,omitempty"`
Val int `xml:"w:val,attr"`
}

View File

@@ -31,10 +31,18 @@ import (
// ParagraphProperties <w:pPr>
type ParagraphProperties struct {
XMLName xml.Name `xml:"w:pPr,omitempty"`
Justification *Justification
Shade *Shade
Kern *Kern
XMLName xml.Name `xml:"w:pPr,omitempty"`
Justification *Justification
Shade *Shade
Kern *Kern
Style *Style
TextAlignment *TextAlignment
AdjustRightInd *AdjustRightInd
SnapToGrid *SnapToGrid
Kinsoku *Kinsoku
OverflowPunct *OverflowPunct
RunProperties *RunProperties
}
// UnmarshalXML ...
@@ -69,6 +77,61 @@ func (p *ParagraphProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElemen
return err
}
p.Kern = &value
case "rPr":
var value RunProperties
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
p.RunProperties = &value
case "pStyle":
p.Style = &Style{Val: getAtt(tt.Attr, "val")}
case "textAlignment":
p.TextAlignment = &TextAlignment{Val: getAtt(tt.Attr, "val")}
case "adjustRightInd":
var value AdjustRightInd
v := getAtt(tt.Attr, "val")
if v == "" {
continue
}
value.Val, err = strconv.Atoi(v)
if err != nil {
return err
}
p.AdjustRightInd = &value
case "snapToGrid":
var value SnapToGrid
v := getAtt(tt.Attr, "val")
if v == "" {
continue
}
value.Val, err = strconv.Atoi(v)
if err != nil {
return err
}
p.SnapToGrid = &value
case "kinsoku":
var value Kinsoku
v := getAtt(tt.Attr, "val")
if v == "" {
continue
}
value.Val, err = strconv.Atoi(v)
if err != nil {
return err
}
p.Kinsoku = &value
case "overflowPunct":
var value OverflowPunct
v := getAtt(tt.Attr, "val")
if v == "" {
continue
}
value.Val, err = strconv.Atoi(v)
if err != nil {
return err
}
p.OverflowPunct = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {
@@ -177,27 +240,6 @@ func (p *Paragraph) String() string {
return sb.String()
}
// MarshalXML ...
func (p *Paragraph) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
err := e.EncodeToken(start)
if err != nil {
return err
}
if p.Properties != nil {
err = e.Encode(p.Properties)
if err != nil {
return err
}
}
for _, c := range p.Children {
err = e.Encode(c)
if err != nil {
return err
}
}
return e.EncodeToken(start.End())
}
// UnmarshalXML ...
func (p *Paragraph) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for _, attr := range start.Attr {
@@ -243,6 +285,7 @@ func (p *Paragraph) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
elem = &value
case "r":
var value Run
value.file = p.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err

View File

@@ -47,16 +47,6 @@ func TestRelationships(t *testing.T) {
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")
@@ -69,7 +59,7 @@ func TestRelationships(t *testing.T) {
t.Fatal(err)
}
m := hex.EncodeToString(h.Sum(make([]byte, 0, 16)))
if m != "c75af73ef6cc9536a193669c4a3605c3" {
if m != "62c753dc14365fce007fc4c7c3bd0c82" {
t.Fatal("real md5:", m)
}
}

View File

@@ -31,16 +31,27 @@ import (
// a piece of text in bold, or a link
type Run struct {
XMLName xml.Name `xml:"w:r,omitempty"`
RsidRPr string `xml:"w:rsidRPr,attr,omitempty"`
RunProperties *RunProperties `xml:"w:rPr,omitempty"`
InstrText string `xml:"w:instrText,omitempty"`
Children []interface{}
file *Docx
}
// UnmarshalXML ...
func (r *Run) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "rsidRPr":
r.RsidRPr = attr.Value
default:
// ignore other attributes
}
}
for {
t, err := d.Token()
if err == io.EOF {
@@ -91,6 +102,7 @@ func (r *Run) parse(d *xml.Decoder, tt xml.StartElement) (child interface{}, err
child = &value
case "drawing":
var value Drawing
value.file = r.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return nil, err
@@ -112,8 +124,14 @@ func (r *Run) parse(d *xml.Decoder, tt xml.StartElement) (child interface{}, err
if ttt, ok := tok.(xml.StartElement); ok && ttt.Name.Local == "Choice" {
for _, attr := range ttt.Attr {
if attr.Name.Local == "Requires" {
if attr.Value == "wps" {
child, err = r.parse(d, ttt)
if attr.Value == "wps" || attr.Value == "wpc" {
tok, err = d.Token() // go into choice
if err != nil {
return nil, err
}
if ttt, ok := tok.(xml.StartElement); ok {
child, err = r.parse(d, ttt)
}
break altcont
}
break
@@ -141,15 +159,18 @@ type RunProperties struct {
XMLName xml.Name `xml:"w:rPr,omitempty"`
Fonts *RunFonts
Bold *Bold
ICs *struct{} `xml:"w:iCs,omitempty"`
Italic *Italic
Underline *Underline
Highlight *Highlight
Color *Color
Size *Size
SizeCs *SizeCs
RunStyle *RunStyle
Style *Style
Shade *Shade
Kern *Kern
VertAlign *VertAlign
}
// UnmarshalXML ...
@@ -174,6 +195,8 @@ func (r *RunProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
r.Fonts = &value
case "b":
r.Bold = &Bold{}
case "iCs":
r.ICs = &struct{}{}
case "i":
r.Italic = &Italic{}
case "u":
@@ -192,6 +215,10 @@ func (r *RunProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
var value Size
value.Val = getAtt(tt.Attr, "val")
r.Size = &value
case "szCs":
var value SizeCs
value.Val = getAtt(tt.Attr, "val")
r.SizeCs = &value
case "rStyle":
var value RunStyle
value.Val = getAtt(tt.Attr, "val")
@@ -218,6 +245,10 @@ func (r *RunProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
return err
}
r.Kern = &value
case "vertAlign":
var value VertAlign
value.Val = getAtt(tt.Attr, "val")
r.VertAlign = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {

View File

@@ -1,3 +1,23 @@
/*
Copyright (c) 2020 gingfrederik
Copyright (c) 2021 Gonzalo Fernandez-Victorio
Copyright (c) 2021 Basement Crowd Ltd (https://www.basementcrowd.com)
Copyright (c) 2023 Fumiama Minamoto (源文雨)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package docx
import (
@@ -7,16 +27,21 @@ import (
"strings"
)
// WPSWordprocessingShape is a container for a WordprocessingML DrawingML shape.
type WPSWordprocessingShape struct {
// WordprocessingShape is a container for a WordprocessingML DrawingML shape.
type WordprocessingShape struct {
XMLName xml.Name `xml:"wps:wsp,omitempty"`
CNvPr *WPSCNvPr
CNvCnPr *WPSCNvCnPr
CNvSpPr *WPSCNvSpPr
SpPr *WPSSpPr
TextBox *WPSTextBox
BodyPr *WPSBodyPr
file *Docx
}
// UnmarshalXML ...
func (w *WPSWordprocessingShape) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
func (w *WordprocessingShape) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err == io.EOF {
@@ -28,18 +53,38 @@ func (w *WPSWordprocessingShape) UnmarshalXML(d *xml.Decoder, start xml.StartEle
if tt, ok := t.(xml.StartElement); ok {
switch tt.Name.Local {
case "cNvPr":
w.CNvPr = new(WPSCNvPr)
err = d.DecodeElement(w.CNvPr, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "cNvCnPr":
w.CNvCnPr = new(WPSCNvCnPr)
err = d.DecodeElement(w.CNvCnPr, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "cNvSpPr":
w.CNvSpPr = new(WPSCNvSpPr)
err = d.DecodeElement(w.CNvSpPr, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "spPr":
w.SpPr = new(WPSSpPr)
err = d.DecodeElement(w.SpPr, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
case "txbx":
var value WPSTextBox
value.file = w.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
w.TextBox = &value
case "bodyPr":
w.BodyPr = new(WPSBodyPr)
err = d.DecodeElement(w.BodyPr, &tt)
@@ -57,6 +102,33 @@ func (w *WPSWordprocessingShape) UnmarshalXML(d *xml.Decoder, start xml.StartEle
return nil
}
// WPSCNvPr is an element that represents the non-visual properties of a content control.
type WPSCNvPr struct {
XMLName xml.Name `xml:"wps:cNvPr,omitempty"`
ID int `xml:"id,attr"`
Name string `xml:"name,attr"`
}
// UnmarshalXML ...
func (r *WPSCNvPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "id":
r.ID, err = strconv.Atoi(attr.Value)
if err != nil {
return
}
case "name":
r.Name = attr.Value
default:
// ignore other attributes
}
}
// Consume the end element
_, err = d.Token()
return
}
// WPSCNvCnPr represents the non-visual drawing properties of a connector.
type WPSCNvCnPr struct {
XMLName xml.Name `xml:"wps:cNvCnPr,omitempty"`
@@ -90,15 +162,76 @@ func (w *WPSCNvCnPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
return nil
}
// WPSCNvSpPr represents the non-visual properties of a WordArt object.
type WPSCNvSpPr struct {
XMLName xml.Name `xml:"wps:cNvSpPr,omitempty"`
TxBox int `xml:"txBox,attr,omitempty"`
SPLocks *ASPLocks
}
// UnmarshalXML ...
func (w *WPSCNvSpPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "txBox":
w.TxBox, err = strconv.Atoi(attr.Value)
if err != nil {
return err
}
default:
// ignore other attributes
}
}
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 "spLocks":
var value ASPLocks
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
w.SPLocks = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
continue
}
}
}
return nil
}
// ASPLocks represents the locks applied to a shape.
type ASPLocks struct {
XMLName xml.Name `xml:"a:spLocks,omitempty"`
}
// WPSSpPr is a container element that represents the visual properties of a shape.
type WPSSpPr struct {
XMLName xml.Name `xml:"wps:spPr,omitempty"`
BWMode string `xml:"bwMode,attr"`
Xfrm AXfrm
PrstGeom APrstGeom
NoFill *struct{} `xml:"a:noFill,omitempty"`
Elems []interface{}
Xfrm AXfrm
PrstGeom APrstGeom
SolidFill *ASolidFill
BlipFill *ABlipFill
NoFill *struct{} `xml:"a:noFill,omitempty"`
Line *ALine
EffectList struct{} `xml:"a:effectLst"`
ExtList struct{} `xml:"a:extLst"`
}
// UnmarshalXML ...
@@ -129,6 +262,20 @@ func (w *WPSSpPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
}
case "prstGeom":
w.PrstGeom.Prst = getAtt(tt.Attr, "prst")
case "solidFill":
var value ASolidFill
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
w.SolidFill = &value
case "blipFill":
var value ABlipFill
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
w.BlipFill = &value
case "noFill":
w.NoFill = &struct{}{}
case "ln":
@@ -137,7 +284,7 @@ func (w *WPSSpPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
w.Elems = append(w.Elems, &ln)
w.Line = &ln
default:
err = d.Skip() // skip unsupported tags
if err != nil {
@@ -150,14 +297,137 @@ func (w *WPSSpPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
return nil
}
// ABlipFill represents a fill that contains a reference to an image.
type ABlipFill struct {
XMLName xml.Name `xml:"a:blipFill,omitempty"`
DPI int `xml:"dpi,attr"`
RotWithShape int `xml:"rotWithShape,attr"`
Blip *ABlip
SrcRect *ASrcRect
Tile *ATile
}
// UnmarshalXML ...
func (r *ABlipFill) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "dpi":
r.DPI, err = strconv.Atoi(attr.Value)
if err != nil {
return err
}
case "rotWithShape":
r.RotWithShape, err = strconv.Atoi(attr.Value)
if err != nil {
return err
}
default:
// ignore other attributes
}
}
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 "blip":
var value ABlip
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.Blip = &value
case "srcRect":
r.SrcRect = new(ASrcRect)
case "tile":
var value ATile
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.Tile = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
continue
}
}
}
return nil
}
// ASrcRect represents the source rectangle of a tiled image fill.
type ASrcRect struct {
XMLName xml.Name `xml:"a:srcRect,omitempty"`
}
// ATile represents the tiling information of a fill or border
type ATile struct {
XMLName xml.Name `xml:"a:tile,omitempty"`
TX int64 `xml:"tx,attr"`
TY int64 `xml:"ty,attr"`
SX int64 `xml:"sx,attr"`
SY int64 `xml:"sy,attr"`
Flip string `xml:"flip,attr"`
Algn string `xml:"algn,attr"`
}
// UnmarshalXML ...
func (t *ATile) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "tx":
t.TX, err = strconv.ParseInt(attr.Value, 10, 64)
if err != nil {
return err
}
case "ty":
t.TY, err = strconv.ParseInt(attr.Value, 10, 64)
if err != nil {
return err
}
case "sx":
t.SX, err = strconv.ParseInt(attr.Value, 10, 64)
if err != nil {
return err
}
case "sy":
t.SY, err = strconv.ParseInt(attr.Value, 10, 64)
if err != nil {
return err
}
case "flip":
t.Flip = attr.Value
case "algn":
t.Algn = attr.Value
default:
// ignore other attributes
}
}
// Consume the end element
_, err = d.Token()
return err
}
// ALine represents a line element in a Word document.
type ALine struct {
XMLName xml.Name `xml:"a:ln,omitempty"`
W int64 `xml:"w,attr"`
W int64 `xml:"w,attr,omitempty"`
Cap string `xml:"cap,attr,omitempty"`
Compound string `xml:"cmpd,attr,omitempty"`
Align string `xml:"algn,attr,omitempty"`
NoFill *struct{} `xml:"a:noFill,omitempty"`
SolidFill *ASolidFill
PrstDash *APrstDash
Miter *AMiter
@@ -196,6 +466,8 @@ func (l *ALine) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error)
if tt, ok := t.(xml.StartElement); ok {
switch tt.Name.Local {
case "noFill":
l.NoFill = &struct{}{}
case "solidFill":
l.SolidFill = new(ASolidFill)
err = d.DecodeElement(l.SolidFill, &tt)
@@ -351,7 +623,156 @@ func (r *ATailEnd) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
return err
}
// WPSTextBox ...
type WPSTextBox struct {
XMLName xml.Name `xml:"wps:txbx,omitempty"`
Content *WTextBoxContent
file *Docx
}
// UnmarshalXML ...
func (b *WPSTextBox) UnmarshalXML(d *xml.Decoder, start xml.StartElement) 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 "txbxContent":
var value WTextBoxContent
value.file = b.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
b.Content = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
continue
}
}
}
return nil
}
// WTextBoxContent ...
type WTextBoxContent struct {
XMLName xml.Name `xml:"w:txbxContent,omitempty"`
Paragraphs []Paragraph `xml:"w:p,omitempty"`
file *Docx
}
// UnmarshalXML ...
func (c *WTextBoxContent) UnmarshalXML(d *xml.Decoder, start xml.StartElement) 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 "p":
var value Paragraph
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
if len(value.Children) > 0 {
value.file = c.file
c.Paragraphs = append(c.Paragraphs, value)
}
default:
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
continue
}
}
}
return nil
}
// WPSBodyPr represents the body properties for a WordprocessingML DrawingML shape.
type WPSBodyPr struct {
XMLName xml.Name `xml:"wps:bodyPr,omitempty"`
XMLName xml.Name `xml:"wps:bodyPr,omitempty"`
Rot int `xml:"rot,attr,omitempty"`
Vert string `xml:"vert,attr,omitempty"`
Wrap string `xml:"wrap,attr,omitempty"`
LIns int64 `xml:"lIns,attr,omitempty"`
TIns int64 `xml:"tIns,attr,omitempty"`
RIns int64 `xml:"rIns,attr,omitempty"`
BIns int64 `xml:"bIns,attr,omitempty"`
Anchor string `xml:"anchor,attr,omitempty"`
AnchorCtr int `xml:"anchorCtr,attr,omitempty"`
Upright int `xml:"upright,attr,omitempty"`
NoAutofit *struct{} `xml:"a:noAutofit,omitempty"`
}
// UnmarshalXML ...
func (r *WPSBodyPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "rot":
r.Rot, _ = strconv.Atoi(attr.Value)
case "vert":
r.Vert = attr.Value
case "wrap":
r.Wrap = attr.Value
case "lIns":
r.LIns, _ = strconv.ParseInt(attr.Value, 10, 64)
case "tIns":
r.TIns, _ = strconv.ParseInt(attr.Value, 10, 64)
case "rIns":
r.RIns, _ = strconv.ParseInt(attr.Value, 10, 64)
case "bIns":
r.BIns, _ = strconv.ParseInt(attr.Value, 10, 64)
case "anchor":
r.Anchor = attr.Value
case "anchorCtr":
r.AnchorCtr, _ = strconv.Atoi(attr.Value)
case "upright":
r.Upright, _ = strconv.Atoi(attr.Value)
default:
// ignore other attributes
}
}
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 "noAutofit":
r.NoAutofit = &struct{}{}
default:
err = d.Skip() // skip unsupported elements
if err != nil {
return err
}
continue
}
}
}
return nil
}

View File

@@ -1,3 +1,23 @@
/*
Copyright (c) 2020 gingfrederik
Copyright (c) 2021 Gonzalo Fernandez-Victorio
Copyright (c) 2021 Basement Crowd Ltd (https://www.basementcrowd.com)
Copyright (c) 2023 Fumiama Minamoto (源文雨)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package docx
import (
@@ -13,8 +33,8 @@ func TestShapeStructure(t *testing.T) {
// add new paragraph
para1 := w.AddParagraph()
// add text
para1.AddText("test shape")
para1.AddShape(808355, 238760, "AutoShape", "auto", "straightConnector1", []interface{}{
para1.AddText("test anchor shape")
para1.AddAnchorShape(808355, 238760, "AutoShape", "auto", "straightConnector1",
&ALine{
W: 9525,
SolidFill: &ASolidFill{SrgbClr: &ASrgbClr{Val: "000000"}},
@@ -22,7 +42,19 @@ func TestShapeStructure(t *testing.T) {
HeadEnd: &AHeadEnd{},
TailEnd: &ATailEnd{},
},
})
)
para2 := w.AddParagraph()
para2.AddText("test inline shape")
para2.AddInlineShape(808355, 238760, "AutoShape", "auto", "straightConnector1",
&ALine{
W: 9525,
SolidFill: &ASolidFill{SrgbClr: &ASrgbClr{Val: "000000"}},
Round: &struct{}{},
HeadEnd: &AHeadEnd{},
TailEnd: &ATailEnd{},
},
)
f, err := os.Create("TestMarshalShapeStructure.xml")
if err != nil {

View File

@@ -51,11 +51,11 @@ func (t *WTable) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
switch tt.Name.Local {
case "tr":
var value WTableRow
value.file = t.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
value.file = t.file
t.TableRows = append(t.TableRows, &value)
case "tblPr":
t.TableProperties = new(WTableProperties)
@@ -421,11 +421,11 @@ func (w *WTableRow) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
}
case "tc":
var value WTableCell
value.file = w.file
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
value.file = w.file
w.TableCells = append(w.TableCells, &value)
default:
err = d.Skip() // skip unsupported tags
@@ -504,7 +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"`
Rule string `xml:"w:hRule,attr,omitempty"`
Val int64 `xml:"w:val,attr"`
}
@@ -565,9 +565,9 @@ type WTableCellProperties struct {
TableCellWidth *WTableCellWidth
VMerge *WvMerge
GridSpan *WGridSpan
VAlign *WVerticalAlignment
TableBorders *WTableBorders `xml:"w:tcBorders"`
Shade *Shade
VAlign *WVerticalAlignment
}
// UnmarshalXML ...

View File

@@ -7,8 +7,6 @@
<Default Extension="xml" ContentType="application/xml"/>
<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>
<Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/>
<Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/>
<Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/>
<Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>

View File

@@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:settings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex"
xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid"
xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml"
xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"
xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex"
xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh">
<w:zoom w:percent="179"/>
<w:bordersDoNotSurroundHeader/>
<w:bordersDoNotSurroundFooter/>
<w:proofState w:spelling="clean" w:grammar="clean"/>
<w:defaultTabStop w:val="420"/>
<w:characterSpacingControl w:val="doNotCompress"/>
<w:compat>
<w:useFELayout/>
<w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="15"/>
<w:compatSetting w:name="overrideTableStyleFontSizeAndJustification" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/>
<w:compatSetting w:name="enableOpenTypeFeatures" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/>
<w:compatSetting w:name="doNotFlipMirrorIndents" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/>
<w:compatSetting w:name="differentiateMultirowTableHeaders" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/>
<w:compatSetting w:name="useWord2013TrackBottomHyphenation" w:uri="http://schemas.microsoft.com/office/word" w:val="0"/>
</w:compat>
<w:rsids>
<w:rsidRoot w:val="008E4657"/>
<w:rsid w:val="006A5E36"/>
<w:rsid w:val="008E4657"/>
</w:rsids>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="--"/>
<m:smallFrac m:val="0"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr>
<w:themeFontLang w:val="en-US" w:eastAsia="zh-CN"/>
<w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"/>
<w:decimalSymbol w:val="."/>
<w:listSeparator w:val=","/>
<w14:docId w14:val="1FCC31E2"/>
<w15:docId w15:val="{E96752AD-97D3-6946-8F9F-89449BD2C27F}"/>
</w:settings>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:webSettings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex"
xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid"
xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml"
xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"
xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh"/>