package lib import ( "bytes" "errors" "fmt" "io" "os" "path/filepath" "strings" "time" "gitlab.com/romalor/pdflib/pkg/components/attachment" "gitlab.com/romalor/pdflib/pkg/pdf" ) func AppendToPdf( inputPdfFilePath string, inputXmlFilePath string, outputFilePath string, embedName string, description string, ) (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") }() if inputPdfFilePath == "" { return errors.New("no input pdf file specified") } if inputXmlFilePath == "" { inputXmlFilePath = strings.TrimSuffix(inputPdfFilePath, filepath.Ext(inputPdfFilePath)) + ".xml" } if outputFilePath == "" { outputFilePath = strings.TrimSuffix( inputPdfFilePath, filepath.Ext(inputPdfFilePath), ) + "_xml.pdf" } if description == "" { description = "Rechnung" } if embedName == "" { embedName = "factur-x.xml" } logger.Log( fmt.Sprintf( "pdfInput: '%s' xmlInput: '%s' output: '%s'", inputPdfFilePath, inputXmlFilePath, outputFilePath, ), ) var inputFile *os.File inputFile, err = os.Open(inputPdfFilePath) if err != nil { return err } defer inputFile.Close() var result io.Reader result, err = addXmpData(inputFile) if err != nil { return err } result, err = addAttachment(result, inputXmlFilePath, embedName, description) 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 nil, err } var inputXmlFile *os.File inputXmlFile, err = os.Open(inputXmlFilePath) if err != nil { return nil, err } var inputData []byte inputData, err = io.ReadAll(inputXmlFile) if err != nil { return nil, err } err = AddAttachment(doc, attachment.Attachment{ Name: embedName, Description: description, MIMEType: "text/xml", Size: int64(len(inputData)), Relationship: "Alternative", ModDate: time.Now(), }, inputData) if err != nil { return nil, err } result := bytes.NewBuffer([]byte{}) _, err = doc.Writer().WriteTo(result) if err != nil { return nil, err } 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 }