Skip to content

Commit

Permalink
PPT relationships, image fix (unidoc#395)
Browse files Browse the repository at this point in the history
* PPT relationships, image fix

* filenames fix

* Custom properties fix

* schema update

* Table styles fix

* Scale fix

* path fix

* New schema: cycle imports fix

* xsdAny namespace duplicate fix

* Images names fix

* Images extensions fix

* duplicate chart fix

* chart empty attrs fix

* Choice if fixed, scale is rolled back

* comments

* Rollback license info in schema files

* import path fix

* import path fix 2

* error with incorrect content types names fixed when deleting slides and then adding them again

* template with image example

* MustCompile replaced

* imports fixed

* slideIdx error fix
  • Loading branch information
zgordan-vv authored Jun 7, 2020
1 parent 9892c32 commit 2052cbb
Show file tree
Hide file tree
Showing 29 changed files with 641 additions and 74 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 92 additions & 0 deletions _examples/presentation/use-template-with-image/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package main

import (
"fmt"
"os"
"time"

"github.com/unidoc/unioffice/common"
"github.com/unidoc/unioffice/schema/soo/dml"
"github.com/unidoc/unioffice/schema/soo/pml"

"github.com/unidoc/unioffice/presentation"
)

func main() {
startTime := time.Now()

// Start building pptx
ppt, err := presentation.OpenTemplate("template.potx")
if err != nil {
fmt.Println("presentation.OpenTemplate err ", err)
os.Exit(1)
}

// Clear out example slides
for _, s := range ppt.Slides() {
if err = ppt.RemoveSlide(s); err != nil {
fmt.Println("ppt.RemoveSlide err ", err)
os.Exit(1)
}
}

// Add new slide from template
layout, err := ppt.GetLayoutByName("Picture with Caption")
if err != nil {
fmt.Println("ppt.GetLayoutByName err ", err)
os.Exit(1)
}

// Add local image to pptx
image, err := common.ImageFromFile("gophercolor.png")
if err != nil {
fmt.Println("common.ImageFromFile err ", err)
os.Exit(1)
}

iRef, err := ppt.AddImage(image)
if err != nil {
fmt.Println("ppt.AddImage err ", err)
os.Exit(1)
}

slide, err := ppt.AddDefaultSlideWithLayout(layout)
if err != nil {
fmt.Println("ppt.AddDefaultSlideWithLayout err ", err)
os.Exit(1)
}

// Inject content into placeholders
title, _ := slide.GetPlaceholder(pml.ST_PlaceholderTypeTitle)
title.SetText("New title")

body, _ := slide.GetPlaceholder(pml.ST_PlaceholderTypeBody)
body.SetText("New body text")

imageRelID := slide.AddImageToRels(iRef)

pic, err := slide.GetPlaceholder(pml.ST_PlaceholderTypePic)
if err != nil {
fmt.Println("ppt.AddImage err ", err)
os.Exit(1)
}

spPr := dml.NewCT_ShapeProperties()
spPr.BlipFill = dml.NewCT_BlipFillProperties()
spPr.BlipFill.Blip = dml.NewCT_Blip()
spPr.BlipFill.Blip.EmbedAttr = &imageRelID
spPr.BlipFill.Stretch = dml.NewCT_StretchInfoProperties() // stretch to parent block with default values

pic.X().SpPr = spPr

if err := ppt.Validate(); err != nil {
fmt.Println("ppt.Validate err ", err)
}

if err := ppt.SaveToFile("success.pptx"); err != nil {
fmt.Println("ppt.SaveToFile err ", err)
}

duration := time.Now().Sub(startTime).Seconds()
fmt.Println("success! took ", duration, " seconds")
}
Binary file not shown.
1 change: 1 addition & 0 deletions common/customproperties.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ func (c CustomProperties) SetPropertyAsClsid(name string, clsid string) {
}

func (c CustomProperties) SetPropertyAsDate(name string, date time.Time) {
date = date.UTC() // Office 365 shows errors for local time
property := c.getNewProperty(name)
property.Date = &date
c.setProperty(property)
Expand Down
37 changes: 37 additions & 0 deletions common/table_styles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2017 FoxyUtils ehf. 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 via https://unidoc.io website.

package common

import (
"github.com/unidoc/unioffice/schema/soo/dml"
)

// TableStyles contains document specific properties.
type TableStyles struct {
x *dml.TblStyleLst
}

// NewTableStyles constructs a new TableStyles.
func NewTableStyles() TableStyles {
return TableStyles{x: dml.NewTblStyleLst()}
}

// X returns the inner wrapped XML type.
func (t TableStyles) X() *dml.TblStyleLst {
return t.x
}

// DefAttr returns the DefAttr property.
func (t TableStyles) DefAttr() string {
return t.x.DefAttr
}

// TblStyle returns the TblStyle property.
func (t TableStyles) TblStyle() []*dml.CT_TableStyle {
return t.x.TblStyle
}
2 changes: 1 addition & 1 deletion document/document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,6 @@ func TestInsertTableInTable(t *testing.T) {
expected := "table inside table after paragraph 1"
got := cbc2.Tbl[0].EG_ContentRowContent[0].Tr[0].EG_ContentCellContent[0].Tc[0].EG_BlockLevelElts[0].EG_ContentBlockContent[0].P[0].EG_PContent[0].EG_ContentRunContent[0].R.EG_RunInnerContent[0].T.Content
if expected != got {
t.Errorf("expected %s in the second inner table paragraph, got %s", expected, got)
t.Errorf("expected %s in the second inner table paragraph, got %s", expected, got)
}
}
1 change: 0 additions & 1 deletion document/runproperties.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ func (r RunProperties) SetVerticalAlignment(v sharedTypes.ST_VerticalAlignRun) {
}
}


// Bold returns true if run font is bold.
func (r RunProperties) Bold() bool {
x := r.x
Expand Down
42 changes: 42 additions & 0 deletions filenames.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,31 @@ func AbsoluteFilename(dt DocType, typ string, index int) string {
return "docProps/app.xml"
case ThumbnailType, ThumbnailTypeStrict:
return "docProps/thumbnail.jpeg"
case CustomXMLType:
return fmt.Sprintf("customXml/item%d.xml", index)
case PresentationPropertiesType:
return "ppt/presProps.xml"

case ViewPropertiesType:
switch dt {
case DocTypePresentation:
return "ppt/viewProps.xml"
case DocTypeSpreadsheet:
return "xl/viewProps.xml"
case DocTypeDocument:
return "word/viewProps.xml"
}
case TableStylesType:
switch dt {
case DocTypePresentation:
return "ppt/tableStyles.xml"
case DocTypeSpreadsheet:
return "xl/tableStyles.xml"
case DocTypeDocument:
return "word/tableStyles.xml"
}
case HyperLinkType:
return ""

case OfficeDocumentType, OfficeDocumentTypeStrict:
switch dt {
Expand Down Expand Up @@ -117,6 +142,10 @@ func AbsoluteFilename(dt DocType, typ string, index int) string {
switch dt {
case DocTypeSpreadsheet:
return fmt.Sprintf("xl/charts/chart%d.xml", index)
case DocTypeDocument:
return fmt.Sprintf("word/charts/chart%d.xml", index)
case DocTypePresentation:
return fmt.Sprintf("ppt/charts/chart%d.xml", index)
default:
Log("unsupported type %s pair and %v", typ, dt)
}
Expand Down Expand Up @@ -189,13 +218,26 @@ func AbsoluteFilename(dt DocType, typ string, index int) string {
return fmt.Sprintf("ppt/slideLayouts/slideLayout%d.xml", index)
case SlideMasterType:
return fmt.Sprintf("ppt/slideMasters/slideMaster%d.xml", index)
case HandoutMasterType:
return fmt.Sprintf("ppt/handoutMasters/handoutMaster%d.xml", index)
case NotesMasterType:
return fmt.Sprintf("ppt/notesMasters/notesMaster%d.xml", index)

default:
Log("unsupported type %s", typ)
}
return ""
}

// RelativeImageFilename returns an image filename relative to the source file referenced
// from a relationships file. It is identical to RelativeFilename but is used particularly for images
// in order to handle different image formats.
func RelativeImageFilename(dt DocType, relToTyp, typ string, index int, fileExtension string) string {
filename := RelativeFilename(dt, relToTyp, typ, index)
// replace "png" with the actual file extension
return filename[0:len(filename)-3] + fileExtension
}

// AbsoluteImageFilename returns the full path to an image from the root of the
// zip container.
func AbsoluteImageFilename(dt DocType, index int, fileExtension string) string {
Expand Down
1 change: 1 addition & 0 deletions presentation/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"os"
)

// OpenTemplate opens a template file.
func OpenTemplate(fn string) (*Presentation, error) {
p, err := Open(fn)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions presentation/placeholder.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func (s PlaceHolder) Clear() {
para.EndParaRPr.LangAttr = unioffice.String("en-US")
}

// Remove removes a placeholder from a presentation.
func (s PlaceHolder) Remove() error {
for i, spChc := range s.sld.CSld.SpTree.Choice {
for _, sp := range spChc.Sp {
Expand Down
58 changes: 58 additions & 0 deletions presentation/pres_props.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2017 FoxyUtils ehf. 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 via https://unidoc.io website.

package presentation

import (
"github.com/unidoc/unioffice/schema/soo/dml"
"github.com/unidoc/unioffice/schema/soo/pml"
)

// PresentationProperties contains document specific properties.
type PresentationProperties struct {
x *pml.PresentationPr
}

// NewPresentationProperties constructs a new PresentationProperties.
func NewPresentationProperties() PresentationProperties {
return PresentationProperties{x: pml.NewPresentationPr()}
}

// X returns the inner wrapped XML type.
func (p PresentationProperties) X() *pml.PresentationPr {
return p.x
}

// HtmlPubPr returns the HtmlPubPr property.
func (p PresentationProperties) HtmlPubPr() *pml.CT_HtmlPublishProperties {
return p.x.HtmlPubPr
}

// WebPr returns the WebPr property.
func (p PresentationProperties) WebPr() *pml.CT_WebProperties {
return p.x.WebPr
}

// PrnPr returns the PrnPr property.
func (p PresentationProperties) PrnPr() *pml.CT_PrintProperties {
return p.x.PrnPr
}

// ShowPr returns the ShowPr property.
func (p PresentationProperties) ShowPr() *pml.CT_ShowProperties {
return p.x.ShowPr
}

// ClrMru returns the ClrMru property.
func (p PresentationProperties) ClrMru() *dml.CT_ColorMRU {
return p.x.ClrMru
}

// ExtLst returns the ExtLst property.
func (p PresentationProperties) ExtLst() *pml.CT_ExtensionList {
return p.x.ExtLst
}
Loading

0 comments on commit 2052cbb

Please sign in to comment.