Produce Facture-x/ZUGFeRD invoices | Port reference from upstream repo
This is neither a feature report / nor bug request.
Goal
Use react-pdf to issue electronic invoices (Facture-x / ZUGFeRD). This requires attaching XML data, adding some XMP markup and a valid PDF/A3 pdf.
Contribute back / my issue
To implement this I forked this repo and I would like to contribute back, as a lot of changes involve #2613.
Basically I ported the the new reference class from the upstream pdfkit repo.
This works fine except one issue: When adding custom fonts, they look like this (there should be one word "Lorem"):
@diegomura Do you have any idea what might be happening here? The issue must be somewhere at the intersection between the upstream repo's new reference class and how custom fonts are embedded. Maybe there is some overlap with PR in #2696 by @klimeryk
Further implementation
Once the issue can be resolved and all tests run, I can split work into several more granular PRs. I have a prototype with these features implemented.
- [ ] Port reference and PDF/A compliance from pdfkit. Might be beneficial for long-term goal to use upstream repo again.
- [ ] Allow file attachments
- [ ] XML component to add XML metadata
- [ ] Fixed for the pdfkit lib to actually produce valid PDF/A3 (this is a PR I would also open against upstream, as they have a small spec derivation when attaching files)
Update: Turns out the issue is related to the fontkit upgrade. Using [email protected] like the upstream repo works. Not sure how to proceed. Maintainers, please advise.
I implemented everything for Facture-x / ZUGFeRD compliance (see screenshot).
<Document
attachments={[
{
content: exampleXml,
creationDate: new Date(2020, 3, 1),
description: 'ZUGFeRD Invoice Data',
hidden: false,
modifiedDate: new Date(2020, 3, 1),
name: 'zugferd-invoice.xml',
relationship: 'Alternative',
type: 'application/xml',
},
]} // new prop to add PDF attachments
author="Test GmbH"
creationDate={new Date()}
creator="Test GmbH"
keywords="test"
onRender={onRender}
pdfVersion="1.7"
producer="Test"
subject="Test"
subset="PDF/A-3" // new prop to specify PDF subset
tagged // new props to specify whether PDF should be tagged or not, necessary for PDF/A3 compliance
title="Test"
>
<Page>
<Text style={{ fontFamily: 'Inter' }}>Lorem</Text>
<Xml value={`some XML metadata, shortened for brevity`}/>
</Page>
</Document>
Thanks for working on this, @florianbepunkt! And for the ping - I've ran into font issue as well for my PR, so I'm curious and excited that you were able to fix the issues by downgrading fontkit! (https://github.com/florianbepunkt/react-pdf/commit/349c5e5af8973f5adb5c30f5be7d94ee8ef8aa33) I'll try the same for my PR and will report back if that fixes the issues.
@klimeryk It might be good to check the whole commit history (it's not huge), but I was not 100% sharp in aligning my commits, as there was some back and forth. Reverting to fontkit<2.0 means, you loose browser compatibility. So this is a first step, but maybe we can find out why that is and how to fix it.
@klimeryk Interesting find... I think I found the underlying issue. Missed a small point when checking fontkit's release notes (unfortunately they don't have a proper changelog):
Encoding subsets is now no longer streaming. subset.encodeStream() has been replaced with subset.encode() which returns a Uint8Array.
I believe the fix is to simply change this line https://github.com/diegomura/react-pdf/blob/c0ec5d8d434b6c936c30d36a431e53256590e0d8/packages/pdfkit/src/font/embedded.js#L152
from
fontFile.end(this.subset.encode());
to
fontFile.end(Buffer.from(this.subset.encode()));
The interesting part: How the heck did this work before?? I honestly have no clue. But with this change we should be good to go. This should solve the font issue in your PR as well. Can you check?
I would wait if we hear something from the maintainer, so we can finish this PR.
Awesome find, @florianbepunkt! I've tested with my PR and it indeed fixes the font issue! 💖 See https://github.com/klimeryk/react-pdf/commit/16f14754427e47ba3b28136dcccd257f42731e20. I've only done quick test, but everything looked like it should - I'll give it a closer look and update the description of my PR tomorrow-ish 🤞 Thank you so much for connecting the dots here - I've been meaning to dig into these font issues, but never got around to it. Super stoked to see it was just a simple one line fix in the end! Though, of course, finding that one line is the tricky part - so huge kudos to you!
That would be an great feature. Actually I need this!
@florianbepunkt Wow, great work! I would love to see your implementation being merged! Your fork is a little behind the current react-pdf master. Any chance you can provide some yarn patches or patch package to apply your changes?
@diegomura Would you be interested in this? I can create a new PR that implements
- PDF/A spec including compliant font impl
- Spec compliant attachments
- XML primitive to embedd xml data
- Node 22 compatability
This would allow to create Zugferd/Facture-X invoices. Also I can start on getting rid of some outdated / unused deps (e. g. updating canvas to v3, getting rid of cross-fetch, etc.). Let me know.
This would be a great feature to be added, and currently blocks us from using react pdf :)