Go implementation of the Open Packaging Conventions (OPC)

opc

PkgGoDev Build Status Go Report Card codecov codeclimate License Mentioned in Awesome Go

Package opc implements the ISO/IEC 29500-2, also known as the Open Packaging Convention.

The Open Packaging specification describes an abstract model and physical format conventions for the use of XML, Unicode, ZIP, and other openly available technologies and specifications to organize the content and resources of a document within a package.

The OPC is the foundation technology for many new file formats: .docx, .pptx, .xlsx, .3mf, .dwfx, ...

Features

  • Package reader and writer
  • Package core properties and relationships
  • Part relationships
  • ZIP mapping
  • Package, relationships and parts validation against specs
  • Part interleaved pieces
  • Digital signatures

Examples

Write

// Create a file to write our archive to.
f, _ := os.Create("example.xlsx")

// Create a new OPC archive.
w := opc.NewWriter(f)

// Create a new OPC part.
name := opc.NormalizePartName("docs\\readme.txt")
part, _ := w.Create(name, "text/plain")

// Write content to the part.
part.Write([]byte("This archive contains some text files."))

// Make sure to check the error on Close.
w.Close()

Read

r, _ := opc.OpenReader("testdata/test.xlsx")
defer r.Close()

// Iterate through the files in the archive,
// printing some of their contents.
for _, f := range r.Files {
  fmt.Printf("Contents of %s with type %s :\n", f.Name, f.ContentType)
  rc, _ := f.Open()
  io.CopyN(os.Stdout, rc, 68)
  rc.Close()
  fmt.Println()
}
Owner
Quim Muntal
Eager traveler, passionate engineer and polyglot programmer.
Quim Muntal
Comments
  • Delete parts or update existing parts

    Delete parts or update existing parts

    Hi,

    I'm trying to update a file in a package. I naively tried to simply re-add it after modification but this returns the following:

    a package shall not contain equivalent part names
    

    Is it possible to delete a part in the package or even just update it with a modified version?

  • Unable to add new parts to existing package

    Unable to add new parts to existing package

    Hi,

    I have a problem reopening an existing file and adding further parts to it.

    I reopen the file with the following:

    p.reader, err = opc.OpenReader(outputFilePath)
    p.writer, err = opc.NewWriterFromReader(&bytes.Buffer{}, p.reader.Reader)
    

    and I get no error. In the debugger I can also see that the correct file is opened with files added previously.

    However, when I attach new files using:

    name := opc.NormalizePartName(contentType.PackagePath + "/" + fileName)
    part, err := p.writer.Create(name, contentType.Value)
    bytes, err := ioutil.ReadFile(contentFilePath)
    // Write content to the part.
    part.Write(bytes)
    

    I see in the debugger that everything is added to the object but nothing is finally added to the file.

    I also tried

    part, err := p.writer.CreatePart(&opc.Part{
            Name:        name,
    	ContentType: contentType.Value,
    }, opc.CompressionNormal)
    

    instead of

    part, _ := p.writer.Create(name, contentType.Value)
    

    but it has the same effect.

    What am I doing wrong or is there a bug?

  • Missing Dublin Core complex type in the Core Properties XML

    Missing Dublin Core complex type in the Core Properties XML

    According to Notes on the W3C XML Schemas for Qualified Dublin Core, the Core properties dates should be serialized with xsi:type="dcterms:W3CDTF" like dcterms:created and dcterms:modified in the below example:

    <?xml version="1.0" encoding="UTF-8"?>
    <coreProperties xmlns="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:dcterms="http://purl.org/dc/terms/"
        xmlns:dcmitype="http://purl.org/dc/dcmitype/"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <dcterms:created xsi:type="dcterms:W3CDTF">2020-10-15T04:05:00Z</dcterms:created>
        <dc:creator>Microsoft Office User</dc:creator>
        <lastModifiedBy>Microsoft Office User</lastModifiedBy>
        <dcterms:modified xsi:type="dcterms:W3CDTF">2020-10-15T04:07:00Z</dcterms:modified>
        <revision>2</revision>
    </coreProperties>
    

    Microsoft Office validator complains when xsi:type="dcterms:W3CDTF" is missing

  • [Content_Types].xml should not containg an override part of itself

    [Content_Types].xml should not containg an override part of itself

    MS Office does not open a document when Content_Types.xml contains an override part of itself

        <Override PartName="/[Content_Types].xml" ContentType="text/xml"></Override>
    
  • Improve Unicode support

    Improve Unicode support

    • Part names with valid IRI syntax are now accepted when writing a package
    • NormalizePartName correctly escape IRI and URI sub-delims and other no-reserved characters
  • Add NewWriterFromReader

    Add NewWriterFromReader

    NewWriterFromReader is a helper function that created a new Writer with the content of a Reader. This facilitate the task of modifying core properties and package relationships and appending parts to a package.

  • Workaround to set the CoreProperties relationship ID

    Workaround to set the CoreProperties relationship ID

    New CoreProperties member: RelationshipID. Like PartName, it is not serialized in the XML.

    Microsoft Office requires the relationship ID values honoring the pattern rIdNNN where NNN is a positive number. This change will allow users to predefine the ID to bypass

  • Relationship Target attribute shall be relative to the

    Relationship Target attribute shall be relative to the "parent" part

    According to the specs:

    The package implementer might allow a TargetMode to be provided by a producer. [O1.5] The TargetMode indicates whether or not the target describes a resource inside the package or outside the package. The valid values, in the Relationships schema, are Internal and External. The default value is Internal. When set to Internal, the Target attribute shall be a relative reference and that reference is interpreted relative to the “parent” part. For package relationships, the package implementer shall resolve relative references in the Target attribute against the pack URI that identifies the entire package resource. [M1.29] For more information, see Annex B.

    func relativePart() {
    	filename := "test_files/relative_parts.zip"
    	f, _ := os.Create(filename)
    	w := opc.NewWriter(f)
    
    	contentType := "plain/text"
    	names := []string{"one", "two", "three", "four"}
    
    	var parts []*opc.Part
    
    	prev := ""
    	for _, relativeName := range names {
    		name := prev + "/" + relativeName + ".txt"
    		parts = append(parts, &opc.Part{Name: name, ContentType: contentType})
    		prev = prev + "/" + relativeName
    	}
    	var i int
    	for i = 0; i < len(names)-1; i++ {
    		parts[i].Relationships = append(parts[i].Relationships,
    			&opc.Relationship{ID: strconv.Itoa(i), TargetMode: opc.ModeInternal, TargetURI: names[i+1], Type: contentType})
    		pw, _ := w.CreatePart(parts[i], opc.CompressionNone)
    		_, _ = pw.Write([]byte(names[i]))
    	}
    	pw, _ := w.CreatePart(parts[i], opc.CompressionNone)
    	pw.Write([]byte(names[i]))
    
    	w.Close()
    }
    

    The above code creates a package with absolutes Targets that actually are wrong. Probably the normalizeTargetURI() needs some refactory.

    An example of the wrong absolute path at _one/two/rels/three.txt.rels

    <?xml version="1.0" encoding="UTF-8"?>
    <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
        <Relationship Id="2" Type="plain/text" Target="/four"></Relationship>
    </Relationships>
    
s3fs provides a S3 implementation for Go1.16 filesystem interface.

S3 FileSystem (fs.FS) implementation.Since S3 is a flat structure, s3fs simulates directories by using prefixes and "/" delim. ModTime on directories is always zero value.

Nov 9, 2022
An implementation of the FileSystem interface for tar files.

TarFS A wrapper around tar.Reader. Implements the FileSystem interface for tar files. Adds an Open method, that enables reading of file according to i

Sep 26, 2022
A Go io/fs filesystem implementation for reading files in a Github gists.

GistFS GistFS is an io/fs implementation that enables to read files stored in a given Gist. Requirements This module depends on io/fs which is only av

Oct 14, 2022
A norms and conventions validator for Terraform

This tool will help you ensure that a terraform folder answer to your norms and conventions rules. This can be really useful in several cases : You're

Nov 29, 2022
Controller-check - Run checks against K8s controllers to verify if they meets certain conventions

controller-check Run checks against K8s controllers to verify if they meets cert

Jan 4, 2022
a build tool for Go, with a focus on cross-compiling, packaging and deployment

goxc NOTE: goxc has long been in maintenance mode. Ever since Go1.5 supported simple cross-compilation, this tool lost much of its value. There are st

Dec 9, 2022
a build tool for Go, with a focus on cross-compiling, packaging and deployment

goxc NOTE: goxc has long been in maintenance mode. Ever since Go1.5 supported simple cross-compilation, this tool lost much of its value. There are st

Dec 9, 2022
Packaging and encrypting/decrypting your files for Golang

?? Paket – A vault to packaging and encrypt/decrypt your files in golang! pkg.go.dev | Table of Contents ?? Informations ??‍?? ??‍?? What does it do ?

Aug 19, 2022
Automatically creates Debian packaging for Go packages

dh-make-golang is a tool to automatically create Debian packaging for Go packages. Its goal is to automate away as much of the work as possible when c

Nov 25, 2022
Nomad Pack is a templating and packaging tool used with HashiCorp Nomad.

Nomad Pack is a templating and packaging tool used with HashiCorp Nomad.

Jan 4, 2023
Docker For Go Application Packaging And Pushing To Docker Hub

DOCKER-FOR-GO-APPLICATION-PACKAGING-AND-PUSHING-TO-DOCKER-HUB ##DOCKER COMMANDS: (Don't forget to navigate to the directory that contains the app and

Jan 22, 2022
Ubuntu packaging of conainerd. :D
Ubuntu packaging of conainerd. :D

containerd is an industry-standard container runtime with an emphasis on simplicity, robustness and portability. It is available as a daemon for Linux

Nov 14, 2021
Tanzu Framework provides a set of building blocks to build atop of the Tanzu platform and leverages Carvel packaging

Tanzu Framework provides a set of building blocks to build atop of the Tanzu platform and leverages Carvel packaging and plugins to provide users with a much stronger, more integrated experience than the loose coupling and stand-alone commands of the previous generation of tools.

Dec 16, 2022
Source code related to an on-site demonstration (for Ardan Labs) of packaging Go applications with Nix

Ardan Labs Nix Demo High-Level Overview We bumbled the scheduling of an earlier presentation about git worktree that a few co-workers attended. In eff

Oct 12, 2022
Tools for the Gio project, most notably gogio for packaging Gio programs

Gio Tools Tools for the Gio project, most notably gogio for packaging Gio programs. Issues File bugs and TODOs through the issue tracker or send an em

Oct 5, 2022
Go language implementation of a blockchain based on the BDLS BFT protocol. The implementation was adapted from Ethereum and Sperax implementation

BDLS protocol based PoS Blockchain Most functionalities of this client is similar to the Ethereum golang implementation. If you do not find your quest

Oct 14, 2022
Feishu/Lark Open API Go Sdk, Support ALL Open API and Event Callback.

lark 中文版 README Feishu/Lark Open API Go Sdk, Support ALL Open API and Event Callback. Created By Code Generation. Install go get github.com/chyroc/lar

Jan 5, 2023
Open-IM-Server is open source instant messaging Server.Backend in Go.
Open-IM-Server is open source instant messaging Server.Backend in Go.

Open-IM-Server Open-IM-Server: Open source Instant Messaging Server Instant messaging server. Backend in pure Golang, wire transport protocol is JSON

Jan 2, 2023
Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core network solution.
Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core network solution.

Connecting the Next Billion People Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core

Dec 31, 2022
SigNoz helps developers monitor their applications & troubleshoot problems, an open-source alternative to DataDog, NewRelic, etc. 🔥 🖥. 👉 Open source Application Performance Monitoring (APM) & Observability tool
SigNoz helps developers monitor their applications & troubleshoot problems, an open-source alternative to DataDog, NewRelic, etc. 🔥 🖥.   👉  Open source Application Performance Monitoring (APM) & Observability tool

Monitor your applications and troubleshoot problems in your deployed applications, an open-source alternative to DataDog, New Relic, etc. Documentatio

Sep 24, 2021