document: support creating inline images

Fixes #134
This commit is contained in:
Todd 2017-12-10 07:36:12 -06:00
parent 323695ec80
commit 12b7484103
4 changed files with 119 additions and 0 deletions

Binary file not shown.

View File

@ -41,6 +41,15 @@ func main() {
run := para.AddRun()
for i := 0; i < 16; i++ {
run.AddText(lorem)
// drop an inline image in
if i == 13 {
inl, err := run.AddDrawingInline(iref)
if err != nil {
log.Fatalf("unable to add inline image: %s", err)
}
inl.SetSize(1*measurement.Inch, 1*measurement.Inch)
}
}
doc.SaveToFile("image.docx")
}

46
document/inlinedrawing.go Normal file
View File

@ -0,0 +1,46 @@
// Copyright 2017 Baliance. All rights reserved.
//
// Use of this source code is governed by the terms of the Affero GNU General
// Public License version 3.0 as published by the Free Software Foundation and
// appearing in the file LICENSE included in the packaging of this file. A
// commercial license can be purchased by contacting sales@baliance.com.
package document
import (
"baliance.com/gooxml/common"
"baliance.com/gooxml/measurement"
pic "baliance.com/gooxml/schema/soo/dml/picture"
"baliance.com/gooxml/schema/soo/wml"
)
// InlineDrawing is an inlined image within a run.
type InlineDrawing struct {
d *Document
x *wml.WdInline
}
// X returns the inner wrapped XML type.
func (i InlineDrawing) X() *wml.WdInline {
return i.x
}
// GetImage returns the ImageRef associated with an InlineDrawing.
func (i InlineDrawing) GetImage() (common.ImageRef, bool) {
any := i.x.Graphic.GraphicData.Any
if len(any) > 0 {
p, ok := any[0].(*pic.Pic)
if ok {
if p.BlipFill != nil && p.BlipFill.Blip != nil && p.BlipFill.Blip.EmbedAttr != nil {
return i.d.GetImageByRelID(*p.BlipFill.Blip.EmbedAttr)
}
}
}
return common.ImageRef{}, false
}
// SetSize sets the size of the displayed image on the page.
func (i InlineDrawing) SetSize(w, h measurement.Distance) {
i.x.Extent.CxAttr = int64(float64(w*measurement.Pixel72) / measurement.EMU)
i.x.Extent.CyAttr = int64(float64(h*measurement.Pixel72) / measurement.EMU)
}

View File

@ -208,3 +208,67 @@ func (r Run) AddDrawingAnchored(img common.ImageRef) (AnchoredDrawing, error) {
return ad, nil
}
// AddDrawingInline adds an inline drawing from an ImageRef.
func (r Run) AddDrawingInline(img common.ImageRef) (InlineDrawing, error) {
ic := r.newIC()
ic.Drawing = wml.NewCT_Drawing()
inl := wml.NewWdInline()
inline := InlineDrawing{r.d, inl}
// required by Word on OSX for the file to open
//anchor.SimplePosAttr = gooxml.Bool(false)
//anchor.AllowOverlapAttr = true
inl.CNvGraphicFramePr = dml.NewCT_NonVisualGraphicFrameProperties()
ic.Drawing.Inline = append(ic.Drawing.Inline, inl)
inl.Graphic = dml.NewGraphic()
inl.Graphic.GraphicData = dml.NewCT_GraphicalObjectData()
inl.Graphic.GraphicData.UriAttr = "http://schemas.openxmlformats.org/drawingml/2006/picture"
inl.DistTAttr = gooxml.Uint32(0)
inl.DistLAttr = gooxml.Uint32(0)
inl.DistBAttr = gooxml.Uint32(0)
inl.DistRAttr = gooxml.Uint32(0)
inl.Extent.CxAttr = int64(float64(img.Size().X*measurement.Pixel72) / measurement.EMU)
inl.Extent.CyAttr = int64(float64(img.Size().Y*measurement.Pixel72) / measurement.EMU)
// Mac Word chokes if the ID is greater than an int32, even though the field is a
// uint32 in the XSD
randID := 0x7FFFFFFF & rand.Uint32()
inl.DocPr.IdAttr = randID
p := pic.NewPic()
p.NvPicPr.CNvPr.IdAttr = randID
// find the reference to the actual image file in the document relationships
// so we can embed via the relationship ID
imgID := img.RelID()
if imgID == "" {
return inline, errors.New("couldn't find reference to image within document relations")
}
inl.Graphic.GraphicData.Any = append(inl.Graphic.GraphicData.Any, p)
p.BlipFill = dml.NewCT_BlipFillProperties()
p.BlipFill.Blip = dml.NewCT_Blip()
p.BlipFill.Blip.EmbedAttr = &imgID
p.BlipFill.Stretch = dml.NewCT_StretchInfoProperties()
p.BlipFill.Stretch.FillRect = dml.NewCT_RelativeRect()
p.SpPr = dml.NewCT_ShapeProperties()
// Required to allow resizing
p.SpPr.Xfrm = dml.NewCT_Transform2D()
p.SpPr.Xfrm.Off = dml.NewCT_Point2D()
p.SpPr.Xfrm.Off.XAttr.ST_CoordinateUnqualified = gooxml.Int64(0)
p.SpPr.Xfrm.Off.YAttr.ST_CoordinateUnqualified = gooxml.Int64(0)
p.SpPr.Xfrm.Ext = dml.NewCT_PositiveSize2D()
p.SpPr.Xfrm.Ext.CxAttr = int64(img.Size().X * measurement.Point)
p.SpPr.Xfrm.Ext.CyAttr = int64(img.Size().Y * measurement.Point)
// required by Word on OSX for the image to display
p.SpPr.PrstGeom = dml.NewCT_PresetGeometry2D()
p.SpPr.PrstGeom.PrstAttr = dml.ST_ShapeTypeRect
return inline, nil
}