Barcode in PDF not displaying in FireFox [duplicate] - java

I am running into strange issue with generated pdf's from iText7. The generated pdf's are opening properly in Adobe reader and Chrome browser. But the same pdf is opening partially in the Firefox browser. I am getting the below message in Firefox. The strange thing is other pdf, which are not generated via iText are properly rendering in firefox.
Java code
public static byte[] createPdf(List<String> htmlPages, PageSize pageSize, boolean rotate) throws IOException {
ConverterProperties properties = new ConverterProperties();
// Register classpath protocol handler to be able to load HTML resources from class patch
org.apache.catalina.webresources.TomcatURLStreamHandlerFactory.register();
properties.setBaseUri("classpath:/");
// properties.setBaseUri(baseUri);
FontProvider fontProvider = new DefaultFontProvider(true,false,false);
properties.setFontProvider(fontProvider);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfDocument pdf = new PdfDocument(new PdfWriter(byteArrayOutputStream));
PdfMerger merger = new PdfMerger(pdf);
for (String htmlPage : htmlPages) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfDocument temp = new PdfDocument(new PdfWriter(baos));
if(rotate) {
temp.setDefaultPageSize(pageSize.rotate()); /** Page Size and Orientation */
} else {
temp.setDefaultPageSize(pageSize); /** Page Size and Orientation */
}
HtmlConverter.convertToPdf(htmlPage, temp, properties);
temp = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())));
merger.merge(temp, 1, temp.getNumberOfPages());
temp.close();
}
pdf.close();
byteArrayOutputStream.flush(); // Tried this
byteArrayOutputStream.close(); // Tried this
byte[] byteArray = byteArrayOutputStream.toByteArray();
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
try (FileOutputStream fileOuputStream = new FileOutputStream("D:\\Labels\\Label_"+timestamp.getTime()+".pdf")){
fileOuputStream.write(byteArray);
}
return byteArray;
}
Thanks in advance.
Edit 1:
You can find pdf and html/css for reproducing issue here.

When you embedded the images into your html using base64 URIs, something weird happened to the image of the barcode: Instead of the 205×59 bitmap image in labelData/barcode.png you embedded a 39578×44 image! (Yes, an image nearly a thousand times wider than high...)
The iText HtmlConverter embedded that image just fine but apparently Firefox has issues displaying an image with those dimensions even though (or probably because?) it is transformed into the desired dimensions (about four times wider than high) on the label. At least my Firefox installation stops drawing label contents right here. (Beware, the order of drawing in the PDF content is not identical to the of the HTML elements; in particular in the PDF the number 3232000... is drawn right before the barcode, not afterwards!)
On Firefox:
On Acrobat Reader:
Thus, you may want to check the transformation of the bar code image to the base64 image URI in your HTML file.

Related

iText/Java When converting HTML to PDF, the text positioning does not match

I use iText to convert HTML to PDF. In general, everything works as it should, but there is a problem with some font families. After the conversion, the height positioning of fonts in a PDF document does not match what it was in HTML. An example in the picture below (on the left is the generated PDF, on the right is a preview of the PDF document):
In the image:
(1) - the font Arial - with it all right.
(2) - the font Times New Roman - in PDF it rose to 2px.
(3) - the Dancing Script font - in PDF it dropped to 5px.
(4) - the Tangerine font - it’s all right.
(5) - the Charmonman font - in PDF it dropped to 5px.
For HTML template, which is generated in PDF specified CSS styles exactly the same as used to preview PDF document.
PDF is generated as follows:
private byte[] getPdf(StringBuilder fileText) throws IOException {
FontProvider fontProvider = new FontProvider(addCertificateFonts(), "");
fontProvider.addStandardPdfFonts();
ConverterProperties properties = new ConverterProperties().setFontProvider(fontProvider);
properties.setBaseUri(getBaseProjectUri());
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
HtmlConverter.convertToPdf(fileText.toString(), out, properties);
return out.toByteArray();
}
}
private FontSet addCertificateFonts() {
FontSet set = new FontSet();
List<String> fontPaths = //здесь список путей к файлам шрифтов
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
for (String path : fontPaths) {
set.addFont(context.getRealPath(path));
}
return set;
}
Is there any way to fix the font positioning?
Is it possible that the fonts themselves have some configurations that may affect the position of the text with this font?

itext 7 (java) add image on a new page to the end of an existing pdf document

i'm new to itext 7. I have a list of documents with different content that I want to merge into a single PDF. The content types are PDF, JPG & PNG.
My problem is that as soon as I merge a PDF and an image, the image is written over the already inserted content of the target PDF.
How do I get each image to be added to a new page of the target PDF?
This is my Code:
byte[] mergeInhalt(List<Dokument> dokumentList) throws IOException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
PdfWriter pdfWriter = new PdfWriter(byteOut);
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
Document completeDocument = new Document(pdfDocument);
for (Dokument dokument : dokumentList) {
byte[] inhalt = dokument.getInhalt();
if (Objects.nonNull(inhalt)) {
switch (dokument.getFormat().name()) {
case "PDF":
addPdf(pdfDocument, inhalt);
break;
case "JPG":
case "PNG":
ImageData data = ImageDataFactory.create(inhalt);
Image image = new Image(data);
completeDocument.add(image);
break;
}
}
}
completeDocument.close();
return byteOut.toByteArray();
}
private void addPdf(PdfDocument pdfDocument, byte[] inhalt) throws IOException {
PdfReader pdfReader = new PdfReader(new ByteArrayInputStream(inhalt));
PdfDocument pdfDocumentToMerge = new PdfDocument(pdfReader);
pdfDocumentToMerge.copyPagesTo(1, pdfDocumentToMerge.getNumberOfPages(), pdfDocument);
}
Merging PDFs only works well, but everytime i merge a Image i get this:
The image with the pink one was placed over the text of the previous PDF
In your code you add the image via the Document completeDocument but you add the pdf via the underlying PdfDocument pdfDocument. Thus, the completeDocument doesn't know about the added pdf, continues on its current page, and draws over the imported pages.
To make sure each image is added on a new page after the currently last one, you have to tell completeDocument to move its current page:
case "JPG":
case "PNG":
ImageData data = ImageDataFactory.create(inhalt);
Image image = new Image(data);
completeDocument.add(new AreaBreak(AreaBreakType.LAST_PAGE));
completeDocument.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
completeDocument.add(image);
break;
For an example compare the tests testMergeLikeAndreasHuber and testMergeLikeAndreasHuberImproved in CopyPdfsAndImages and their outputs.

Problem drawing some 16bit transparent images with PDPageContentStream.drawImage after updating PDFBox from Version 2.08 to 2.12/2.16

I've some very basic code which inserts an image into an existing PDF:
public class InsertImg
{
public static void main (final String[] args) throws IOException
{
PDDocument document = PDDocument.load (new File ("original.pdf"));
PDPage page = document.getPage (0);
byte[] imgBytes = Files.readAllBytes (Paths.get ("signature.png"));
PDImageXObject pdImage = PDImageXObject.createFromByteArray (document, imgBytes, "name_of_image");
PDPageContentStream content = new PDPageContentStream (document, page, AppendMode.APPEND, true, true);
content.drawImage (pdImage, 50.0f, 350.0f, 100.0f, 25.0f);
content.close ();
document.save (new File ("result.pdf"));
document.close ();
}
}
While this code worked fine in PdfBox 2.08 for all image files, it works under version 2.012 only for some images and does not work anymore for all image files.
(Background: We would like to insert an image of a signature into an existing and already generated letter. The signatures are all generated with the same software. In version 2.12 not all signatures can be inserted anymore. In version 2.08 all signature could be inserted).
The generated pdf-file "result.pdf" cannot be opened in Acrobat Reader. Acrobat Reader shows only the original pdf "original.pdf", but does not display the signature-image. It says "error in page. please contact the creator of the pdf".
However, most images can be inserted, so it is likely that the problem depends on the very image used.
The images are all ok, they are png's and where checked and verified with various imaging programs, e.g. gimp or irfanview.
Furthermore, the code above has always worked fine with PdfBox 2.08. After an update of PdfBox to version 2.12, the problem showed up and also the newest version 2.16 still produces the error. Still on the same image files, and still not on all.
NB: When I put the following line into comment, then no error shows up in Acrobat Reader, so the problem must be somewhere within drawImage.
// content.drawImage (pdImage, 50.0f, 350.0f, 100.0f, 25.0f);
and the rest of the code seems to be fine.
Also, I've just tried starting with an empty PDF and not loading an already generated one.
PDDocument document = new PDDocument ();
PDPage page = new PDPage ();
document.addPage (page);
[...]
The problem here is still the same, so the issue does not depend on the underlying PDF.
It is a bug since 2.0.12 (wrong alternate colorspace for gray images created with the LosslessFactory) that has been fixed in PDFBOX-4607 and will be in release 2.0.17. Display works for all viewers I have tested except Adobe Reader, despite that the alternate colorspace shouldn't be used when an ICC colorspace is available. Here's some code to fix PDFs (this assumes that images are only on top level of a page, i.e. images in other structures are not considered)
for (PDPage page : doc.getPages())
{
PDResources resources = page.getResources();
if (resources == null)
{
continue;
}
for (COSName name : resources.getXObjectNames())
{
PDXObject xObject = resources.getXObject(name);
if (xObject instanceof PDImageXObject)
{
PDImageXObject img = (PDImageXObject) xObject;
if (img.getColorSpace() instanceof PDICCBased)
{
PDICCBased icc = (PDICCBased) img.getColorSpace();
if (icc.getNumberOfComponents() == 1 && PDDeviceRGB.INSTANCE.equals(icc.getAlternateColorSpace()))
{
List<PDColorSpace> list = new ArrayList<>();
list.add(PDDeviceGray.INSTANCE);
icc.setAlternateColorSpaces(list);
}
}
}
}
}

Apache PdfBox Rotate Crop Box Only Not Text

I am trying to go from text to pdf but have only one of the pages rotated 90 degress. Main reason is that some of my text documents are a bit too large and need to be in landscape to look normal. I have tried a few things but it seems like everything rotates the text too. Is there an easy way to rotate the pdf to landscape but keep the text the same rotation?
OutputStream outputStream = response.getOutputStream();
PDFMergerUtility pdfMergerUtility = new PDFMergerUtility();
Map<String, Documents> documents = getDocuments(user, documentReports);
try (PDDocument documentToPrint = new PDDocument()){
for(Document doc : documentReports){
TextToPDF textToPDF = new TextToPDF();
textToPDF.setFont(PDType1Font.COURIER);
textToPDF.setFontSize(8);
Document documentReport = documents.get(doc.getId());
try(PDDocument pdDocument = textToPDF.createPDFFromText(new InputStreamReader(new ByteArrayInputStream(documentReport.getReportText().getBytes())))) {
pdfMergerUtility.appendDocument(documentToPrint, pdDocument);
}
}
pdfMergerUtility.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
LocalDateTime localUtcTime = Java8TimeUtil.getCurrentUtcTime();
documentToPrint.getDocumentInformation().setTitle(localUtcTime.toString());
response.setHeader("Content-Disposition", "inline; filename=" + localUtcTime + ".pdf");
response.setContentType("application/pdf");
documentToPrint.save(outputStream);
}
So this might not work for everyone but I figured it out for my specific requirement. TextToPDF has a method called setLandscape before creating the pdf from text. textToPDF.setLandscape(true);

Remain only used font subsets while splitting PDF in Java

I am using iText to split a PDF document into separate pages as PDF files. Each file seems to be too large as all fonts used in the input PDF are saved into all result pages, which is apparently not very clean.
Code of splitting is as below. Notice PdfSmartCopy and setFullCompression doesn't help to reduce size (which I have no idea why).
public List<byte[]> split(byte[] input) throws IOException, DocumentException {
PdfReader pdfReader = new PdfReader(input);
List<byte[]> pdfFiles = new ArrayList<>();
int pageCount = pdfReader.getNumberOfPages();
int pageIndex = 0;
while (++pageIndex <= pageCount) {
Document document = new Document(pdfReader.getPageSizeWithRotation(pageIndex));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfCopy pdfCopy = new PdfSmartCopy(document, byteArrayOutputStream);
pdfCopy.setFullCompression();
PdfImportedPage pdfImportedPage = pdfCopy.getImportedPage(pdfReader, pageIndex);
document.open();
pdfCopy.addPage(pdfImportedPage);
document.close();
pdfCopy.close();
pdfFiles.add(byteArrayOutputStream.toByteArray());
}
return pdfFiles;
}
So is there a way in Java (iText or not) to solve these problem?
Update with demo PDF
Here is a 377KB PDF using multiple CJK fonts where any page in it using 1 or 2 fonts. The summary size of sub-PDFs is 1.2MB. Considering CJK fonts are very bloated, I would like to find a way to remove unused font and even remove unused characters in used fonts.
So my idea is to remain only used characters in used fonts and embed them in sub files and then un-embed all other fonts. Any advice?

Categories

Resources