feat: added xmp data
This commit is contained in:
+85
-12
@@ -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
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user