Closed cristalp closed 2 years ago
We always create PDF/A documents, to be precise: PDF/A-2b.
This library does not create PDF files compliant with PDF/A. So you must be using some sort of PDF post-processing. How exactly are you doing it?
However, I recently also validated with a couple of online PDF validators. And PDF Online shows this error:
What PDF have you validated? A PDF generated by this library, or one with additional content or post processing?
Can you provide a sample that doesn't validate? I've generated multiple PDFs with the library and they all validated at PDF Online without error.
Well, we're using iText 7.1.9 and adding the QR code to a PdfADocument
that's created with PdfAConformanceLevel.PDF_A_2B
.
So the QR code is embedded in an invoice letter. Is it possible to send you the PDF directly without posting it here?
If you are using iText, then you must have implemented your own Canvas based on iText instead of the standard PDFCanvas based on PDFBox.
If so, the bug must be either in your Canvas implementation (e.g. forgetting to call endText()
), or in iText. It cannot be in this library as you are not using any of the PDF related features of this library.
Well, the code looks like this, doc
being the iText Document
:
final BillFormat format = new BillFormat();
format.setGraphicsFormat(GraphicsFormat.SVG);
format.setFontFamily(ARIAL_FONT_FAMILY);
format.setLanguage(Language.valueOf(data.getSprache().getISOCode().toUpperCase(Locale.ENGLISH)));
bill.setFormat(format);
final FontProvider fontProvider = getFonts().getFontProvider();
final SvgConverterProperties converterProperties = new SvgConverterProperties();
converterProperties.setFontProvider(fontProvider);
SvgConverter.drawOnPage(new String(QRBill.generate(bill), StandardCharsets.UTF_8),
doc.getPdfDocument().getLastPage(), QR_CODE_X, QR_CODE_Y, converterProperties);
Thanks for providing the code. It shows that no custom canvas is involved. Instead, an SVG image is created with the Swiss QR bill library and then iText is used to convert and integrate the SVG image into a PDF document.
My conclusion is that the problem is likely in iText (e.g. in its SvgConverter) and with less likelihood in your code. It certainly cannot be in the Swiss QR bill as - the way it is used here - it generates SVG and not PDF. SVG is a technology independent from PDF and cannot lead to this kind of low-level PDF errors.
Thus, you don't need to send me a sample PDF file. If you are certain the bug is not in your code, you have to send it to iText instead.
Ok, thanks a lot for the analysis. I'll close the issue and try to contact the iText team.
A last remark regarding the validation error. It indicates that graphics (lines, rectangles and other shapes) and text operations are mixed, which would be invalid. In iText, you have to call beginText()
before using text operations and endText()
after using text operations. Most likely, this is violated, i.e. beginText()
is called, some text operations are executed but then graphics operations are used without calling endText()
.
This could be the case in the SvgConverter
class, or in your code. Before submitting a bug description to iText, you might want to check that you have called endText()
before calling SvgConverter.drawOnPage()
.
Hello cristalp, May be you can avoid the SVG convertion with iText and just incorporate the PDF generated by Swiss QR bill generator. Something like this :
com.lowagie.text.pdf.PdfContentByte content;
// Generate your PdfContent
[...]
net.codecrete.qrbill.generator.Bill bill = new net.codecrete.qrbill.generator.Bill();
// Initialise your QR bill
[...]
byte[] bytes = net.codecrete.qrbill.generator.QRBill.generate(bill);
com.lowagie.text.pdf.PdfReader pdfReader = new com.lowagie.text.pdf.PdfReader(bytes);
com.lowagie.text.pdf.PdfWriter pdfWriter = content.getPdfWriter();
com.lowagie.text.pdf.PdfImportedPage importedPage = pdfWriter.getImportedPage(pdfReader, 1);
content.addTemplate(importedPage, 0, 0);
@AbraxasCari Thanks, but it seems like we're not talking about the same iText version. Do you use iText 5? Because I can't find e.g. PdfContentByte in https://api.itextpdf.com/iText7/java/7.1.9/
@manuelbl
Ok, but beginText()
and endText()
seems to be pretty low-level, right? We're only using the high-level Document
. And I'm by no means an iText expert :-)
But looking at their code in SvgConverter.drawOnPage
, a new PdfCanvas
is created from the current page. The SVG is converted to a PdfFormXObject
and then added to the new Canvas.
@AbraxasCari Thanks, but it seems like we're not talking about the same iText version. Do you use iText 5? Because I can't find e.g. PdfContentByte in https://api.itextpdf.com/iText7/java/7.1.9/
Yes, sorry, I took the code from an opensource iText version I have : openpdf 1.3.23. It should probably be possible to do the same thing, unfortunately I don't know the new API. What I can add in my previous example is where the "PdfContentByte" object can be obtained from -> from a PdfWriter (class that still exists, but no longer its getDirectContent() method that is used hereafter....):
PdfContentByte content = pdfWriter.getDirectContent()
@cristalp Yes, they are low-level functions. If you are not using them, then the "bug" is unlikely to be in your software.
We always create PDF/A documents, to be precise: PDF/A-2b.
I'm validating them with veraPDF, and they all pass fine, including the ones with a Swiss QR Bill.
However, I recently also validated with a couple of online PDF validators. And PDF Online shows this error:
Other validators show the PDF to be valid PDF/A-2b. I nailed down the error to just the QR Bill, so it has to be the reason.
I just wanted to point this out. I'm by no means a PDF expert, I hope you are :-)
And thanks a lot for your work, we've saved a lot of time using your software!