feat: added xmp data

This commit is contained in:
2026-02-07 16:09:34 +01:00
parent b659359a79
commit 1196274498
17 changed files with 513 additions and 46 deletions
+85 -12
View File
@@ -1,6 +1,7 @@
package lib
import (
"bytes"
"errors"
"fmt"
"io"
@@ -19,10 +20,13 @@ func AppendToPdf(
outputFilePath string,
embedName string,
description string,
) error {
) (err error) {
logger := GetDebugLogger()
logger.Log(fmt.Sprintf("enter appendToPdf(%s, %s, %s)", inputPdfFilePath, inputXmlFilePath, outputFilePath))
defer func() {
if err != nil {
logger.Log("append err:", err)
}
logger.Log("leave appendToPdf")
}()
@@ -58,30 +62,62 @@ func AppendToPdf(
),
)
inputFile, err := os.Open(inputPdfFilePath)
var inputFile *os.File
inputFile, err = os.Open(inputPdfFilePath)
if err != nil {
return err
}
defer inputFile.Close()
var doc *pdf.Document
doc, err = pdf.OpenReaderWithOptions(inputFile, pdf.OpenOptions{
var result io.Reader
result, err = addAttachment(inputFile, inputXmlFilePath, embedName, description)
if err != nil {
return err
}
result, err = addXmpData(result)
if err != nil {
return err
}
var outputFile *os.File
outputFile, err = os.Create(outputFilePath)
if err != nil {
return err
}
defer outputFile.Close()
_, err = io.Copy(outputFile, result)
if err != nil {
return err
}
return nil
}
func addAttachment(
data io.Reader,
inputXmlFilePath string,
embedName string,
description string,
) (io.Reader, error) {
doc, err := pdf.OpenReaderWithOptions(data, pdf.OpenOptions{
Writable: true,
})
if err != nil {
return err
return nil, err
}
var inputXmlFile *os.File
inputXmlFile, err = os.Open(inputXmlFilePath)
if err != nil {
return err
return nil, err
}
var inputData []byte
inputData, err = io.ReadAll(inputXmlFile)
if err != nil {
return err
return nil, err
}
err = doc.AddAttachment(attachment.Attachment{
@@ -93,15 +129,52 @@ func AppendToPdf(
ModDate: time.Now(),
}, inputData)
if err != nil {
return err
return nil, err
}
logger.Log(doc.Writer().Version)
err = doc.Writer().SaveAs(outputFilePath)
result := bytes.NewBuffer([]byte{})
_, err = doc.Writer().WriteTo(result)
if err != nil {
return err
return nil, err
}
return nil
return result, nil
}
func addXmpData(data io.Reader) (io.Reader, error) {
doc, err := pdf.OpenReaderWithOptions(data, pdf.OpenOptions{
Writable: true,
})
if err != nil {
return nil, err
}
var xmpData []byte
xmpData, err = doc.XMPMetadata()
if err != nil {
return nil, err
}
xmpData, err = addFacturXXmpData(xmpData)
if err != nil {
return nil, err
}
err = doc.SetXMPMetadata(xmpData)
if err != nil {
return nil, err
}
xmpData, err = doc.XMPMetadata()
if err != nil {
return nil, err
}
result := bytes.NewBuffer([]byte{})
_, err = doc.Writer().WriteTo(result)
if err != nil {
return nil, err
}
return result, nil
}
+73
View File
@@ -0,0 +1,73 @@
package lib
import (
xmpbase "github.com/trimmer-io/go-xmp/models/xmp_base"
"github.com/trimmer-io/go-xmp/xmp"
)
const (
FacturXNamespace = "Factur-X PDFA Erweiterungsschema"
FacturXUri = "urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#"
FacturXPrefix = "fx:"
)
func addFacturXXmpData(data []byte) ([]byte, error) {
doc := &xmp.Document{}
err := xmp.Unmarshal(data, doc)
if err != nil {
return nil, err
}
// --- Register Factur-X namespace ---
ns := &xmp.Namespace{
Name: "fx",
URI: FacturXUri,
Factory: func(name string) xmp.Model {
return &xmpbase.XmpBase{}
},
}
xmp.Register(ns)
_, err = doc.MakeModel(ns)
if err != nil {
return nil, err
}
// --- Set Factur-X properties ---
err = doc.SetPath(xmp.PathValue{
Path: FacturXPrefix + "ConformanceLevel",
Namespace: FacturXUri,
Value: "EN 16931",
})
if err != nil {
return nil, err
}
err = doc.SetPath(xmp.PathValue{
Path: FacturXPrefix + "DocumentType",
Namespace: FacturXUri,
Value: "INVOICE",
})
if err != nil {
return nil, err
}
err = doc.SetPath(xmp.PathValue{
Path: FacturXPrefix + "DocumentFileName",
Namespace: FacturXUri,
Value: "factur-x.xml",
})
if err != nil {
return nil, err
}
err = doc.SetPath(xmp.PathValue{
Path: FacturXPrefix + "Version",
Namespace: FacturXUri,
Value: "1.0",
})
if err != nil {
return nil, err
}
return xmp.Marshal(doc)
}