diff --git a/apirun.go b/apirun.go index 32e9627..182db8f 100644 --- a/apirun.go +++ b/apirun.go @@ -10,9 +10,9 @@ func (r *Run) Color(color string) *Run { } // Size allows to set run size -func (r *Run) Size(size int) *Run { +func (r *Run) Size(size string) *Run { r.RunProperties.Size = &Size{ - Val: size * 2, + Val: size, } return r diff --git a/cmd/main/main.go b/cmd/main/main.go index 9dbac7d..ee67fab 100644 --- a/cmd/main/main.go +++ b/cmd/main/main.go @@ -23,10 +23,10 @@ func main() { // add text para1.AddText("test") - para1.AddText("test font size").Size(22) + para1.AddText("test font size").Size("44") para1.AddText("test color").Color("808080") para2 := w.AddParagraph() - para2.AddText("test font size and color").Size(22).Color("ff0000") + para2.AddText("test font size and color").Size("44").Color("ff0000") nextPara := w.AddParagraph() nextPara.AddLink("google", `http://google.com`) @@ -83,5 +83,17 @@ func main() { } fmt.Print("End of paragraph\n\n") } + f, err = os.Create("tmp.docx") + if err != nil { + panic(err) + } + _, err = doc.WriteTo(f) + if err != nil { + panic(err) + } + err = f.Close() + if err != nil { + panic(err) + } fmt.Println("End of main") } diff --git a/structdoc.go b/structdoc.go index 7bc3a38..e62d0db 100644 --- a/structdoc.go +++ b/structdoc.go @@ -8,6 +8,15 @@ const ( XMLNS_WP = `http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing` ) +func getAtt(atts []xml.Attr, name string) string { + for _, at := range atts { + if at.Name.Local == name { + return at.Value + } + } + return "" +} + type Body struct { XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main body"` Paragraphs []*Paragraph `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main p"` diff --git a/structdoc_test.go b/structdoc_test.go index 9ae866d..16297bf 100644 --- a/structdoc_test.go +++ b/structdoc_test.go @@ -2,6 +2,7 @@ package docxlib import ( "encoding/xml" + "io" "os" "testing" ) @@ -570,9 +571,9 @@ func TestMarshalDrawingStructure(t *testing.T) { para1.AddText("直接粘贴 inline") para2 := w.AddParagraph() - para2.AddText("test font size and color").Size(22).Color("ff0000") - para2.AddText("test font size and color").Size(22).Color("ff0000") - para2.AddText("test font size and color").Size(22).Color("ff0000") + para2.AddText("test font size and color").Size("44").Color("ff0000") + para2.AddText("test font size and color").Size("44").Color("ff0000") + para2.AddText("test font size and color").Size("44").Color("ff0000") nextPara := w.AddParagraph() nextPara.AddLink("google", `http://google.com`) @@ -581,9 +582,28 @@ func TestMarshalDrawingStructure(t *testing.T) { if err != nil { t.Fatal(err) } + defer f.Close() _, err = marshaller{data: w.Document}.WriteTo(f) if err != nil { t.Fatal(err) } + _, err = f.Seek(0, io.SeekStart) + if err != nil { + t.Fatal(err) + } + w = New() + err = xml.NewDecoder(f).Decode(&w.Document) + if err != nil { + t.Fatal(err) + } + f1, err := os.Create("test1.xml") + if err != nil { + t.Fatal(err) + } + defer f1.Close() + _, err = marshaller{data: w.Document}.WriteTo(f1) + if err != nil { + t.Fatal(err) + } t.Fail() } diff --git a/structdrawing.go b/structdrawing.go new file mode 100644 index 0000000..a8c0638 --- /dev/null +++ b/structdrawing.go @@ -0,0 +1,70 @@ +package docxlib + +import ( + "encoding/xml" + "io" +) + +// Drawing element contains photos +type Drawing struct { + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main drawing,omitempty"` + Inline *WPInline +} + +func (r *Drawing) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + for { + t, err := d.Token() + if err == io.EOF { + break + } + + switch tt := t.(type) { + case xml.StartElement: + switch tt.Name.Local { + case "inline": + r.Inline = new(WPInline) + r.Inline.DistT = getAtt(tt.Attr, "distT") + r.Inline.DistB = getAtt(tt.Attr, "distB") + r.Inline.DistL = getAtt(tt.Attr, "distL") + r.Inline.DistR = getAtt(tt.Attr, "distR") + d.DecodeElement(r.Inline, &start) + default: + continue + } + } + + } + return nil + +} + +// WPInline wp:inline +type WPInline struct { + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing inline,omitempty"` + DistT string `xml:"distT,attr"` + DistB string `xml:"distB,attr"` + DistL string `xml:"distL,attr"` + DistR string `xml:"distR,attr"` +} + +func (r *WPInline) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + for { + t, err := d.Token() + if err == io.EOF { + break + } + + switch tt := t.(type) { + case xml.StartElement: + switch tt.Name.Local { + case "inline": + + default: + continue + } + } + + } + return nil + +} diff --git a/structlink.go b/structlink.go new file mode 100644 index 0000000..29043e6 --- /dev/null +++ b/structlink.go @@ -0,0 +1,34 @@ +package docxlib + +import ( + "encoding/xml" + "io" +) + +// Hyperlink element contains links +type Hyperlink struct { + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main hyperlink,omitempty"` + ID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr"` + Run Run +} + +func (r *Hyperlink) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + for { + t, err := d.Token() + if err == io.EOF { + break + } + + switch tt := t.(type) { + case xml.StartElement: + if tt.Name.Local == "r" { + d.DecodeElement(&r.Run, &start) + } else { + continue + } + } + + } + return nil + +} diff --git a/structnodes.go b/structpara.go similarity index 100% rename from structnodes.go rename to structpara.go diff --git a/structrun.go b/structrun.go index 5606b70..e25438d 100644 --- a/structrun.go +++ b/structrun.go @@ -19,69 +19,6 @@ type Run struct { Drawing *Drawing } -// Text object contains the actual text -type Text struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main t"` - XMLSpace string `xml:"xml:space,attr,omitempty"` - Text string `xml:",chardata"` -} - -// Hyperlink element contains links -type Hyperlink struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main hyperlink,omitempty"` - ID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr"` - Run Run -} - -// Drawing element contains photos -type Drawing struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main drawing,omitempty"` - Inline *WPInline -} - -// WPInline wp:inline -type WPInline struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing inline,omitempty"` - DistT string `xml:"distT,attr"` - DistB string `xml:"distB,attr"` - DistL string `xml:"distL,attr"` - DistR string `xml:"distR,attr"` -} - -// RunProperties encapsulates visual properties of a run -type RunProperties struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main rPr,omitempty"` - Color *Color `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main color,omitempty"` - Size *Size `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main sz,omitempty"` - RunStyle *RunStyle `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main rStyle,omitempty"` - Style *Style `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main pStyle,omitempty"` -} - -// RunStyle contains styling for a run -type RunStyle struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main rStyle,omitempty"` - Val string `xml:"w:val,attr"` -} - -// Style contains styling for a paragraph -type Style struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main 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:"http://schemas.openxmlformats.org/wordprocessingml/2006/main color"` - Val string `xml:"w:val,attr"` -} - -// Size contains the font size -type Size struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main sz"` - Val int `xml:"w:val,attr"` -} - func (r *Run) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for { t, err := d.Token() @@ -118,43 +55,17 @@ func (r *Run) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { return nil } -func (r *Text) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - for { - t, err := d.Token() - if err == io.EOF { - break - } - switch tt := t.(type) { - case xml.CharData: - r.Text = string(tt) // implicitly copy - } - - } - - return nil +// RunProperties encapsulates visual properties of a run +type RunProperties struct { + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main rPr,omitempty"` + Color *Color `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main color,omitempty"` + Size *Size `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main sz,omitempty"` + RunStyle *RunStyle `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main rStyle,omitempty"` + Style *Style `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main pStyle,omitempty"` } -func (r *Hyperlink) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - for { - t, err := d.Token() - if err == io.EOF { - break - } - switch tt := t.(type) { - case xml.StartElement: - if tt.Name.Local == "r" { - d.DecodeElement(&r.Run, &start) - } else { - continue - } - } - - } - return nil - -} -func (r *Drawing) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { +func (r *RunProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { for { t, err := d.Token() if err == io.EOF { @@ -164,65 +75,54 @@ func (r *Drawing) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { switch tt := t.(type) { case xml.StartElement: switch tt.Name.Local { - case "inline": - r.Inline = new(WPInline) - r.Inline.DistT = getAtt(tt.Attr, "distT") - r.Inline.DistB = getAtt(tt.Attr, "distB") - r.Inline.DistL = getAtt(tt.Attr, "distL") - r.Inline.DistR = getAtt(tt.Attr, "distR") - d.DecodeElement(r.Inline, &start) + case "color": + var value Color + value.Val = getAtt(tt.Attr, "val") + r.Color = &value + case "sz": + var value Size + value.Val = getAtt(tt.Attr, "val") + r.Size = &value + case "rStyle": + var value RunStyle + value.Val = getAtt(tt.Attr, "val") + r.RunStyle = &value + case "pStyle": + var value Style + value.Val = getAtt(tt.Attr, "val") + r.Style = &value default: continue } } } - return nil -} -func (r *WPInline) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - for { - t, err := d.Token() - if err == io.EOF { - break - } - - switch tt := t.(type) { - case xml.StartElement: - switch tt.Name.Local { - case "inline": - - default: - continue - } - } - - } - return nil - -} -func (r *RunStyle) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - for { - t, err := d.Token() - if err == io.EOF { - break - } - - switch tt := t.(type) { - case xml.StartElement: - r.Val = getAtt(tt.Attr, "val") - } - - } return nil } -func getAtt(atts []xml.Attr, name string) string { - for _, at := range atts { - if at.Name.Local == name { - return at.Value - } - } - return "" +// RunStyle contains styling for a run +type RunStyle struct { + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main rStyle,omitempty"` + Val string `xml:"w:val,attr"` +} + +// Style contains styling for a paragraph +type Style struct { + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main 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:"http://schemas.openxmlformats.org/wordprocessingml/2006/main color"` + Val string `xml:"w:val,attr"` +} + +// Size contains the font size +type Size struct { + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main sz"` + Val string `xml:"w:val,attr"` } diff --git a/structtext.go b/structtext.go new file mode 100644 index 0000000..9055187 --- /dev/null +++ b/structtext.go @@ -0,0 +1,30 @@ +package docxlib + +import ( + "encoding/xml" + "io" +) + +// Text object contains the actual text +type Text struct { + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/wordprocessingml/2006/main t"` + XMLSpace string `xml:"xml:space,attr,omitempty"` + Text string `xml:",chardata"` +} + +func (r *Text) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + for { + t, err := d.Token() + if err == io.EOF { + break + } + + switch tt := t.(type) { + case xml.CharData: + r.Text = string(tt) // implicitly copy + } + + } + + return nil +} diff --git a/unpack.go b/unpack.go index 9842b9f..88967ff 100644 --- a/unpack.go +++ b/unpack.go @@ -1,16 +1,16 @@ package docxlib -// This contains internal functions needed to unpack (read) a zip file import ( "archive/zip" "bytes" "encoding/xml" ) -// This receives a zip file (word documents are a zip with multiple xml inside) +// unpack receives a zip file (word documents are a zip with multiple xml inside) // and parses the files that are relevant for us: -// 1.-Document -// 2.-Relationships +// +// 1. Document +// 2. Relationships func unpack(zipReader *zip.Reader) (docx *Docx, err error) { docx = new(Docx) for _, f := range zipReader.File {