Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema for: CT_ImageData, CT_OleObject, CT_Shape and support inside (CT_Object). #334

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
60 changes: 60 additions & 0 deletions document/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ type Document struct {
fontTable *wml.Fonts
endNotes *wml.Endnotes
footNotes *wml.Footnotes

//name: zhexiao(肖哲)
zhexiao marked this conversation as resolved.
Show resolved Hide resolved
//date: 2019-10-09
//编写doc数据结构对OLEobject类型的支持,一个公式路径,一个是公式自带的wmf图片路径
//================================start
OleObjectPaths []OleObjectPath
OleObjectWmfPath []OleObjectWmfPath
//================================end

}

// New constructs an empty document that content can be added to.
Expand Down Expand Up @@ -829,16 +838,41 @@ func (d *Document) onNewRelationship(decMap *zippkg.DecodeMap, target, typ strin
if f == nil {
continue
}

if f.Name == target {
path, err := zippkg.ExtractToDiskTmp(f, d.TmpPath)
if err != nil {
return err
}

//name: zhexiao(肖哲)
//date: 2019-10-09
//处理公式自带的wmf图片
//================================start
if strings.Contains(rel.TargetAttr, ".wmf") {
d.OleObjectWmfPath = append(d.OleObjectWmfPath, OleObjectWmfPath{
rid: rel.IdAttr,
path: path,
})

continue
}
//================================end

img, err := common.ImageFromFile(path)
if err != nil {
return err
}

iref = common.MakeImageRef(img, &d.DocBase, d.docRels)

//name: zhexiao(肖哲)
//date: 2019-10-09
//BUG修复:新增图片的relID
//================================start
iref.SetRelID(rel.IdAttr)
//================================end

d.Images = append(d.Images, iref)
files[i] = nil
}
Expand All @@ -851,6 +885,32 @@ func (d *Document) onNewRelationship(decMap *zippkg.DecodeMap, target, typ strin
rel.TargetAttr = rel.TargetAttr[0:len(rel.TargetAttr)-len(newExt)] + ext
}

//name: zhexiao(肖哲)
//date: 2019-10-09
//对文档公式数据的解析
//================================start
case unioffice.OleObjectType:
for _, f := range files {
if f == nil {
continue
}

//fmt.Printf("%#v \n", rel)
zhexiao marked this conversation as resolved.
Show resolved Hide resolved

if f.Name == target {
path, err := zippkg.ExtractToDiskTmp(f, d.TmpPath)
if err != nil {
return err
}

d.OleObjectPaths = append(d.OleObjectPaths, OleObjectPath{
rid: rel.IdAttr,
path: path,
})
}
}
//================================end
zhexiao marked this conversation as resolved.
Show resolved Hide resolved

default:
unioffice.Log("unsupported relationship type: %s tgt: %s", typ, target)
}
Expand Down
54 changes: 54 additions & 0 deletions document/oleobject.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//name: zhexiao(肖哲)
zhexiao marked this conversation as resolved.
Show resolved Hide resolved
//date: 2019-10-10
//一些与公式相关的数据结构体
//================================start
package document

import "github.com/unidoc/unioffice/schema/soo/wml"

type OleObjectPath struct {
rid string
path string
}

type OleObjectWmfPath struct {
rid string
path string
}

type OleObject struct {
oleobject *wml.CT_OleObject
shape *wml.CT_Shape
}

func (o OleObject) Shape() *wml.CT_Shape {
return o.shape
}

func (o OleObject) OleObject() *wml.CT_OleObject {
return o.oleobject
}

func (o OleObject) OleRid() string {
return *o.oleobject.IdAttr
}

func (o OleObject) ImagedataRid() string {
return *o.shape.Imagedata.IdAttr
}

func (o OleObjectPath) Rid() string {
return o.rid
}

func (o OleObjectPath) Path() string {
return o.path
}

func (o OleObjectWmfPath) Rid() string {
return o.rid
}

func (o OleObjectWmfPath) Path() string {
return o.path
}
47 changes: 47 additions & 0 deletions document/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,50 @@ func (r Run) AddDrawingInline(img common.ImageRef) (InlineDrawing, error) {

return inline, nil
}

//name: zhexiao(肖哲)
//date: 2019-10-09
//从doc xml中读取inline类型的图片
//================================start
func (r Run) DrawingInline() []InlineDrawing {
var ret []InlineDrawing
for _, ic := range r.x.EG_RunInnerContent {
if ic.Drawing == nil {
continue
}

for _, inl := range ic.Drawing.Inline {
ret = append(ret, InlineDrawing{r.d, inl})
}
}
return ret
}

//=================================end

//name: zhexiao(肖哲)
//date: 2019-10-10
//从doc xml中读取ole公式对象数据
//================================start
func (r Run) OleObjects() []OleObject {
var ret []OleObject
for _, ic := range r.x.EG_RunInnerContent {
if ic.Object == nil {
continue
}

//读取对象
oleObject := ic.Object.OleObject
shape := ic.Object.Shape

if oleObject == nil || shape == nil {
continue
}

ret = append(ret, OleObject{oleobject: oleObject, shape: shape})
}

return ret
}

//=================================end
29 changes: 29 additions & 0 deletions schema/soo/dml/CT_PositiveSize2D.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,32 @@ func (m *CT_PositiveSize2D) ValidateWithPath(path string) error {
}
return nil
}

//name: zhexiao(肖哲)
//date: 2019-10-15
//计算图片的宽度和长度
//在Open XML里使用了English Metric Units(EMUs)来作为度量单位,比如<wp:extent cx="1943100" cy="1689100"/>
//https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.drawing.wordprocessing.extent?view=openxml-2.8.1
//================================start
type EmuSize struct {
Width string
Height string
}

const (
mm = 36000
cm = 360000
in = 914400
pt = 12700
pc = 152400
pi = 152400
)

//这里只计算返回的单位为PT的大小
func (m *CT_PositiveSize2D) Size() EmuSize {
return EmuSize{
Width: fmt.Sprintf("%spt", strconv.FormatInt(m.CxAttr / pt, 10)),
Height: fmt.Sprintf("%spt", strconv.FormatInt(m.CyAttr / pt, 10))}
}

//================================end
95 changes: 95 additions & 0 deletions schema/soo/wml/CT_Imagedata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//name: zhexiao(肖哲)
//date: 2019-10-10
//新增CT_Shape下面的imagedata解析
//================================start
package wml

import (
"encoding/xml"
"fmt"
"github.com/unidoc/unioffice"
)

type CT_Imagedata struct {
//r:id
IdAttr *string

TitleAttr *string
}

func NewCT_Imagedata() *CT_Imagedata {
ret := &CT_Imagedata{}
return ret
}

func (m *CT_Imagedata) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
if m.IdAttr != nil {
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "r:id"},
Value: fmt.Sprintf("%v", *m.IdAttr)})
}

if m.TitleAttr != nil {
start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "title"},
Value: fmt.Sprintf("%v", *m.TitleAttr)})
}

_ = e.EncodeToken(start)
_ = e.EncodeToken(xml.EndElement{Name: start.Name})
return nil
}

func (m *CT_Imagedata) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
// initialize to default
for _, attr := range start.Attr {
if attr.Name.Space == "http://schemas.openxmlformats.org/officeDocument/2006/relationships" && attr.Name.Local == "id" {
parsed, err := attr.Value, error(nil)
if err != nil {
return err
}
m.IdAttr = &parsed
continue
}

if attr.Name.Space == "urn:schemas-microsoft-com:office:office" && attr.Name.Local == "title" {
parsed, err := attr.Value, error(nil)
if err != nil {
return err
}
m.TitleAttr = &parsed
continue
}
}
lCT_Imagedata:
for {
tok, err := d.Token()
if err != nil {
return err
}
switch el := tok.(type) {
case xml.StartElement:
switch el.Name {
default:
unioffice.Log("skipping unsupported element on CT_Imagedata %v", el.Name)
if err := d.Skip(); err != nil {
return err
}
}
case xml.EndElement:
break lCT_Imagedata
case xml.CharData:
}
}
return nil
}

// Validate validates the CT_OleObject and its children
func (m *CT_Imagedata) Validate() error {
return m.ValidateWithPath("CT_Imagedata")
}

// ValidateWithPath validates the CT_OleObject and its children, prefixing error messages with path
func (m *CT_Imagedata) ValidateWithPath(path string) error {
return nil
}

//================================end
29 changes: 28 additions & 1 deletion schema/soo/wml/CT_Object.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ package wml
import (
"encoding/xml"
"fmt"

"github.com/unidoc/unioffice"
"github.com/unidoc/unioffice/schema/soo/ofc/sharedTypes"
)
Expand All @@ -24,6 +23,14 @@ type CT_Object struct {
DyaOrigAttr *sharedTypes.ST_TwipsMeasure
Drawing *CT_Drawing
Choice *CT_ObjectChoice

//name: zhexiao(肖哲)
//date: 2019-10-10
//新增CT_Object对OLEObject和Shape属性的支持
//================================start
OleObject *CT_OleObject
Shape *CT_Shape
//================================end
}

func NewCT_Object() *CT_Object {
Expand Down Expand Up @@ -111,6 +118,26 @@ lCT_Object:
if err := d.DecodeElement(&m.Choice.Movie, &el); err != nil {
return err
}

//name: zhexiao(肖哲)
//date: 2019-10-10
//解析Shape和Oleobject属性数据
//================================start
case xml.Name{Space: "urn:schemas-microsoft-com:vml", Local: "shape"}:
m.Shape = NewCT_Shape()
if err := d.DecodeElement(&m.Shape, &el); err != nil {
return err
}
//fmt.Printf("%#v \n", m.Shape)

case xml.Name{Space: "urn:schemas-microsoft-com:office:office", Local: "OLEObject"}:
m.OleObject = NewCT_OleObject()
if err := d.DecodeElement(&m.OleObject, &el); err != nil {
return err
}
//fmt.Printf("%#v \n", m.OleObject)
//================================end

default:
unioffice.Log("skipping unsupported element on CT_Object %v", el.Name)
if err := d.Skip(); err != nil {
Expand Down