mirror of
https://github.com/unidoc/unioffice.git
synced 2025-04-25 13:48:53 +08:00

This seems like the better choice, a lot of the logic is shared between the document types, and it allows generating filenames in a single place. The only downside is that you must pass in the document type as some content types have different typical names depending on the document type (e.g. an 'office document' is the main document.xml, workbook.xml and presentation.xml
80 lines
2.3 KiB
Go
80 lines
2.3 KiB
Go
// 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 common
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
|
|
"baliance.com/gooxml"
|
|
"baliance.com/gooxml/schema/schemas.openxmlformats.org/package/2006/relationships"
|
|
)
|
|
|
|
// Relationships represents a .rels file.
|
|
type Relationships struct {
|
|
x *relationships.Relationships
|
|
}
|
|
|
|
// NewRelationships creates a new relationship wrapper.
|
|
func NewRelationships() Relationships {
|
|
return Relationships{x: relationships.NewRelationships()}
|
|
}
|
|
|
|
// X returns the underlying raw XML data.
|
|
func (r Relationships) X() *relationships.Relationships {
|
|
return r.x
|
|
}
|
|
|
|
// Clear removes any existing relationships.
|
|
func (r Relationships) Clear() {
|
|
r.x.Relationship = nil
|
|
}
|
|
|
|
// FindRIDForN returns the relationship ID for the i'th relationship of type t.
|
|
func (r Relationships) FindRIDForN(i int, t string) string {
|
|
for _, rel := range r.x.CT_Relationships.Relationship {
|
|
if rel.TypeAttr == t {
|
|
if i == 0 {
|
|
return rel.IdAttr
|
|
}
|
|
i--
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// AddAutoRelationship adds a relationship with an automatically generated
|
|
// filename based off of the type. It should be preferred over AddRelationship
|
|
// to ensure consistent filenames are maintained.
|
|
func (r Relationships) AddAutoRelationship(dt gooxml.DocType, idx int, ctype string) Relationship {
|
|
return r.AddRelationship(gooxml.RelativeFilename(dt, ctype, idx), ctype)
|
|
}
|
|
|
|
// AddRelationship adds a relationship.
|
|
func (r Relationships) AddRelationship(target, ctype string) Relationship {
|
|
if !strings.HasPrefix(ctype, "http://") {
|
|
log.Printf("relationship type %s should start with 'http://'", ctype)
|
|
}
|
|
rel := relationships.NewRelationship()
|
|
rel.IdAttr = fmt.Sprintf("rId%d", len(r.x.Relationship)+1)
|
|
rel.TargetAttr = target
|
|
rel.TypeAttr = ctype
|
|
r.x.Relationship = append(r.x.Relationship, rel)
|
|
return Relationship{rel}
|
|
}
|
|
|
|
// Relationships returns a slice of all of the relationships.
|
|
func (r Relationships) Relationships() []Relationship {
|
|
ret := []Relationship{}
|
|
for _, x := range r.x.Relationship {
|
|
ret = append(ret, Relationship{x})
|
|
}
|
|
return ret
|
|
}
|