How to convert a byte array into a PDF file? - java

I have the following problem trying to create a PDF from an array of byte recovered from a Web Services output object.
So I have the following situation:
OutFat outFat = callServizioContabRighe(dataEM, esercizio, importo, bolla, numDoc, oda, pIva, contratto);
byte[] pdfByteArray = outFat.getPDF();
ByteArrayOutputStream osPdf = new ByteArrayOutputStream();
if(pdfByteArray != null) {
InputStream is = new ByteArrayInputStream(pdfByteArray);
sun.misc.BASE64Decoder base64Decoder = new BASE64Decoder();
byte[] byteArray64DecodePdf = null;
try {
byteArray64DecodePdf = base64Decoder.decodeBuffer(is);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
try {
osPdf.write(byteArray64DecodePdf);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
if(osPdf != null && pdfByteArray != null){
req.getSession().setAttribute("PdfEM", osPdf); // Usa il PDF recuperato dal WS
}
else {
req.getSession().setAttribute("PdfEM", createPdfEM.createPdf()); // Crea il PDF
}
if(osPdf != null && pdfByteArray != null){
this.baos = osPdf;
}
else {
this.baos = createPdfEM.createPdf(); // CREA IL PDF
}
Ok so I have the pdfByteArray that is the byte array retrieved from the outFat object (the webservice output object) and that represent my PDF.
Now I have to use it to build a PDF and show it into a view.
So to create the PDF I do the following steps:
I create an InputStream object using the pdfByteArray retrieved by the WS.
I decode it (it is in base64 so I need to decode it).
I write the decoded byteArray64DecodePdf into the osPdf outpustream object.
Then, if the previous steps are successful, I put it into my view (otherwise I create my PDF in an alternative way but this is not related to this question).
The problem is that in my view I can't see the content of my PDF but I only see a grey square rather than it.
What could be the problem?
What can I do to save a local copy of my PDF to try to see it on my local system instead into the browser? So I can understand if the problem is in the conversion or elsewhere
Tnx

Related

Apache PDFBox refuses to open temporary created PDF file

I am creating desktop JavaFX application for viewing PDF files. PDFs are at resource folder. I read resourse file as stream, then I create temporary file and use it to convert contents to image and show into ImageView.
currentPdf = new File("current.pdf");
if (!currentPdf.exists()) {
// In JAR
InputStream inputStream = ClassLoader.getSystemClassLoader()
.getResourceAsStream("PDFSample.pdf");
// Copy file
OutputStream outputStream;
try {
outputStream = new FileOutputStream(currentPdf);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
byte[] buffer = new byte[1024];
int length;
try {
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
outputStream.close();
inputStream.close();
} catch(IOException e) {
throw new RuntimeException(e);
}
}
The problem is: when I create regular file with
currentPdf = new File("current.pdf");
Everything works as expected (i get current.pdf created at directory where jar is located). But I want the file to be created at system temp folder and to be deleted on exit from application. I tried this:
try {
currentPdf = File.createTempFile("current",".pdf");
} catch (IOException e) {
throw new RuntimeException(e);
}
currentPdf.deleteOnExit();//also tried to comment this line
And get exception:
Caused by: java.io.IOException: Error: End-of-File, expected line
at org.apache.pdfbox.pdfparser.BaseParser.readLine(BaseParser.java:1517)
at org.apache.pdfbox.pdfparser.PDFParser.parseHeader(PDFParser.java:360)
at org.apache.pdfbox.pdfparser.PDFParser.parse(PDFParser.java:186)
at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1227)
at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1194)
at org.apache.pdfbox.pdmodel.PDDocument.load(PDDocument.java:1165)
at ua.com.ethereal.pdfquiz.Controller.getPdfPageAsImage(Controller.java:147)
At this method:
#SuppressWarnings("unchecked")
public static Image getPdfPageAsImage(File pdfFile, int pageNum) {
Image convertedImage;
try {
PDDocument document = PDDocument.load(pdfFile);
List<PDPage> list = document.getDocumentCatalog().getAllPages();
PDPage page = list.get(pageNum);
BufferedImage image = page.convertToImage(BufferedImage.TYPE_INT_RGB, 128);
convertedImage = SwingFXUtils.toFXImage(image, null);
document.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
return convertedImage;
}
Would appreciate help in resolving this or pointing me on way to read file directly from jar to avoid creating temporary copies.
How do you create the temporary file?
The usual methods make an empty file in the filesystem. That will trip your logic here:
if (!currentPdf.exists()) {
That check is supposedly there to avoid overwriting exiting files, but in this case you have to get rid of it. As it is, you skip your PDF generation code and try to read an empty file.

The inline attachment i save to disk is corrupted

I have a piece of code that read my inbox email. the code identify 2 kind of attachments:
1) The attached files, which are downloaded and saved to a database. This works just fine.
2) The inline attachment (I'm using an image as the attachment in my tests). The code detects this kind of attachment, but when I save them to disk the file seems to be corrupted. I checked the file properties generated and noticed that it had no basic info (pixels, height, width) with it. I think the file is not saved properly when downloaded to disk (I have tried PNG and JPG). I think the file needs to be saved with a kind of mimetype properties so i can open it properly. Any tips please? Thanks in advance.!
Here is a snip of my code:
public void procesMultiPart(Multipart content) throws SQLException {
try {
for (int i = 0; i < content.getCount(); i++) {
BodyPart bodyPart = content.getBodyPart(i);
Object o;
String downloadDirectory = "D:/Attachment/";
o = bodyPart.getContent();
if (o instanceof String) {
System.out.println("procesMultiPart es plainText");
} else if (null != bodyPart.getDisposition() && bodyPart.getDisposition().equalsIgnoreCase(Part.ATTACHMENT)) {
System.out.println("IS ATTACHMENT...");
// i save the attachment to database and is OK..
} else if (bodyPart.getDisposition() == null){
System.out.println("IS AN INLINE ATTACHMENT...");
String fileNameinline = "inline" + i + ".png";
InputStream inStream = bodyPart.getInputStream();
FileOutputStream outStream = new FileOutputStream(new File(downloadDirectory + fileNameinline), true);
byte[] tempBuffer = new byte[4096];// 4 KB
int numRead;
while ((numRead = inStream.read(tempBuffer)) != -1) {
outStream.write(tempBuffer);
}
inStream.close();
outStream.close();
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
The file is corrupted because you are writing it to the disc incorrectly:
outStream.write(tempBuffer);
You should only write as many bytes as you read:
outStream.write(tempBuffer, 0, numRead);
Thanks to everyone for help and tips. I solved the problem. This is how i did it: I notice that when read the email body (where supposes there was just the pasted image) , there was more that just the image, there was a kind of HTML too, so in other words, the body part has multiparts (2 parts in my case), so i have to process each part until find the image, so i can save it.
hope this help someone else.
regards.

converting .webp to .jpeg using Java

i want to convert a .webp image to .jpeg. I have used javax.imageio.ImageIO.
but # line no: 19 bImage = ImageIO.read(fis); returns a null for webp images.
Code is working fine if I try to convert .png ,.gif file format..
can any one help?
public static void imageIoWrite() {
BufferedImage bImage = null;
try {
File initialImage = new File("resources/1.webp");
FileInputStream fis = new FileInputStream(initialImage);
bImage = ImageIO.read(fis); //why it returns null?
if (bImage != null) {
ImageIO.write(bImage, "jpg",
new File("resources/NewImage1.jpg"));
System.out.println("Image file written successfully");
} else {
System.out.println("imag is empty");
}
} catch (IOException e) {
System.out.println("Exception occured :" + e.getMessage());
}
}
It seems that ImageIO is not able to read webp images. As you can read in the docs, the method read returns null in this case. I think that you have to use an additional library to read and write webp images.

Write some part of a bson file into another bson file in java

I have a bson file,(a.bson). I want to read this file and extract some part of it and then save these parts into another BSON file (b.bson).
Currently, I can read my source file (a.bson) using org.bson.BSONEncoder and extract my favorite parts of it (e.g., key1 and key2 for each row of source fila). Now I want to save these data in another bson file (b.bson). In fact, I need to save this data in a bson file because this file has structure a I can easily check rows have contains spacial value or not. I write this code and
import org.bson.BSONEncoder;
public static void createmyFile(File sourceFile) throws FileNotFoundException, IOException {
InputStream inputStream = new BufferedInputStream(new FileInputStream(sourceFile));
BSONDecoder decoder = new BasicBSONDecoder();
try {
while (inputStream.available() > 0) {
BSONObject bsonSingleRow = decoder.readObject(inputStream);
// ---------------------------------------------------------------------
// Write bsonSingleRow.get(key1) & bsonSingleRow.get(key2) into new file
// ---------------------------------------------------------------------
}
} catch (IOException e) {
...
}
}
Please help me to complete above code.
For example if you want 2% (select randomly) data from source file
File file = new File("a.bson");
String path = "b.bson";
BasicBSONEncoder encoder = new BasicBSONEncoder();
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
BSONDecoder decoder = new BasicBSONDecoder();
try {
while (inputStream.available() > 0) {
BSONObject bsonSingleRow = decoder.readObject(inputStream);
c = bsonSingleRow.get("yourKey").toString();
if (Math.random()> .98))
Files.write(Paths.get(path), encoder.encode(bsonSingleRow),StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}
}
} catch (IOException e) {
...
}

Android reading pdf metadata - memory issue

I'm currently building an android application that displays a set of pdf files in a ListView. Instead of just displaying the filename I want to grab the Title from the metadata of the pdf and display that in the list, if the file doesnt have a Title set then just use the filename. I'm using iText atm, here is what I have:
File[] filteredFiles = root.listFiles(filter);
for (int i=0;i<filteredFiles.length;i++) {
try {
File f = filteredFiles[i];
PdfReader reader = new PdfReader(f.getAbsolutePath());
String title = reader.getInfo().get("Title");
reader.close();
//Do other stuff here...
} catch (Exception e) {
e.printStackTrace();
}
}
This works fine, its gets the data I want, but its slowww. Also, sometimes I get memory crashes if the file is over 2MB. Is there a better way of doing this? Maybe a way of getting the metadata without having to actually open the pdf file?
Any help is much appreciated, Thanks.
You can try fast PDFParse library. It optimized for performance & small memory consumption.
File[] filteredFiles = root.listFiles(filter);
for (int i=0;i<filteredFiles.length;i++) {
try {
File f = filteredFiles[i];
PDFDocument reader = new PDFDocument(f.getAbsolutePath());
String title = reader.getDocumentInfo().getTitle();
reader.close();
//Do other stuff here...
} catch (Exception e) {
e.printStackTrace();
}
}

Categories

Resources