How to print HTML to PDF - java

I Want to print html as a pdf. Here is my code. It was not throwing any error but when i open pdf it is showing error
Here is my java code
URL u = new URL("http://localhost/printPdf.Html");
URLConnection uc = u.openConnection();
BufferedInputStream is = new BufferedInputStream(uc.getInputStream());
File outs = new File("D:/HtmlToPdf.pdf")
BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(outs));
byte[] b = new byte[8 * 1024];
int read = 0;
while ((read = is.read(b)) > -1) {
bout.write(b, 0, read);
}
bout.flush();
bout.close();
is.close();
Here is my html file
<html>
<head></head>
<body><div>Hi !!! Example PDF </div></body>
</html>
When i open pdf i am getting this error
Adobe Reader could not open because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded).

You cannot simply write one file format to another. You need to write the HTML in a way according to the PDF specification.
Here is a PDF library you can use: http://pdfbox.apache.org/

Related

merge many pdf files into one pdf files in web application java

I have many pdf files and I have to merge all pdf into one big pdf file and render it into browser.I am using itext. Using this, I am able to merge pdf files into one file into disk but I cannot merge into browser and there is only last pdf in browser..following is my code.. please help me on this.
Thanks in advance.
Document document = new Document();
List<PdfReader> readers =
new ArrayList<PdfReader>();
int totalPages = 0;
ServletOutputStream servletOutPutStream = response.getOutputStream();;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();;
InputStream is=null;
List<InputStream> inputPdfList = new ArrayList<InputStream>();
System.err.println(imageMap.size());
for(byte[] imageList:imageMap)
{
System.out.println(imageList.toString()+" "+imageList.length);
byteArrayOutputStream.write(imageList);
byteArrayOutputStream.writeTo(response.getOutputStream());
is = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
inputPdfList.add(is);
}
response.setContentType("application/pdf");
response.setContentLength(byteArrayOutputStream.size());
System.out.println(inputPdfList.size()+""+inputPdfList.toString());
//Create pdf Iterator object using inputPdfList.
Iterator<InputStream> pdfIterator =
inputPdfList.iterator();
// Create reader list for the input pdf files.
while (pdfIterator.hasNext()) {
InputStream pdf = pdfIterator.next();
PdfReader pdfReader = new PdfReader(pdf);
readers.add(pdfReader);
totalPages = totalPages + pdfReader.getNumberOfPages();
}
// Create writer for the outputStream
PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
//Open document.
document.open();
//Contain the pdf data.
PdfContentByte pageContentByte = writer.getDirectContent();
PdfImportedPage pdfImportedPage;
int currentPdfReaderPage = 1;
Iterator<PdfReader> iteratorPDFReader = readers.iterator();
// Iterate and process the reader list.
while (iteratorPDFReader.hasNext()) {
PdfReader pdfReader = iteratorPDFReader.next();
//Create page and add content.
while (currentPdfReaderPage <= pdfReader.getNumberOfPages()) {
document.newPage();
pdfImportedPage = writer.getImportedPage(
pdfReader,currentPdfReaderPage);
pageContentByte.addTemplate(pdfImportedPage, 0, 0);
currentPdfReaderPage++;
}
currentPdfReaderPage = 1;
}
//Close document and outputStream.
servletOutPutStream.flush();
outputStream.flush();
document.close();
outputStream.close();
servletOutPutStream.close();
System.out.println("Pdf files merged successfully.");
There are numerous errors in your code:
Only write to the response output stream what you want to return to the browser
Your code writes a wild collection of data to the response output stream:
ServletOutputStream servletOutPutStream = response.getOutputStream();;
[...]
for(byte[] imageList:imageMap)
{
[...]
byteArrayOutputStream.writeTo(response.getOutputStream());
[...]
}
[...]
PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
[... merge PDFs into the writer]
servletOutPutStream.flush();
document.close();
servletOutPutStream.close();
This results in many copies of the imageMap elements to be written there and the merged file only to be added thereafter.
What do you expect the browser to do, ignore all the leading source PDF copies until finally the merged PDF appears?
Thus, please only write the merged PDF to the response output stream.
Don't write a wrong content length
It is a good idea to write the content length to the response... but only if you use the correct value!
In your code you write a content length:
response.setContentLength(byteArrayOutputStream.size());
but the byteArrayOutputStream at this time only contains a wild mix of copies of the source PDFs and not yet the final merged PDF. Thus, this will only serve to confuse the browser even more.
Thus, please do not add false headers to the response.
Don't mangle your input data
In the loop
for(byte[] imageList:imageMap)
{
System.out.println(imageList.toString()+" "+imageList.length);
byteArrayOutputStream.write(imageList);
byteArrayOutputStream.writeTo(response.getOutputStream());
is = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
inputPdfList.add(is);
}
you take byte arrays which I assume contain a single source PDF each, pollute the response output stream with them (as mentioned before), and create a collection of input streams where the first one contains the first source PDF, the second one contains the concatenation of the first two source PDFs, the third one the concatenation of the first three source PDFs, etc...
Because you never reset or re-instantiate the byteArrayOutputStream, it only gets bigger and bigger.
Thus, please start or end loops like this with a reset of the byteArrayOutputStream.
(Actually you don't need that loop at all, the PdfReader has a constructor which can immediately take a byte[], no need to wrap it in a byte stream.)
Don't merge PDFs using a plain PdfWriter, use a PdfCopy
You merge the PDFs using a PdfWriter / getImportedPage / addTemplate approach. There are dozens of questions and answer on stack overflow (many of them answered by iText developers) explaining that this usually is a bad idea and that you should use PdfCopy.
Thus, please make use of the many good answers which already exist on this topic here and use PdfCopy for merging.
Don't flush or close streams only because you can
You finalize the response output by closing numerous streams:
//Close document and outputStream.
servletOutPutStream.flush();
outputStream.flush();
document.close();
outputStream.close();
servletOutPutStream.close();
I have not seen a line in which you declared or set that outputStream variable, but even if it contained the response output stream, there is no need to close that because you already close it in the servletOutPutStream variable.
Thus, please remove unnecessary calls like this.
//Suppose we want to merge one pdf with another main pdf
InputStream is1 = null;
if (file1 != null) {
FileInputStream fis1 = new FileInputStream(file1);
byte[] file1Data = new byte[(int) file1.length()];
fis1.read(file1Data);
is1 = new java.io.ByteArrayInputStream(file1Data);
}
//
InputStream mainContent = <ur main content>
org.apache.pdfbox.pdmodel.PDDocument mergedPDF = new org.apache.pdfbox.pdmodel.PDDocument();
org.apache.pdfbox.pdmodel.PDDocument mainDoc = org.apache.pdfbox.pdmodel.PDDocument.load(mainContent);
org.apache.pdfbox.multipdf.PDFMergerUtility merger = new org.apache.pdfbox.multipdf.PDFMergerUtility();
merger.appendDocument(mergedPDF, mainDoc);
PDDocument doc1 = null;
if (is1 != null) {
doc1 = PDDocument.load(is1);
merger.appendDocument(mergedPDF, doc1);
//1st file appended to main pdf");
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
mergedPDF.save(baos);
//Now either u save it here or convert into InputStream if u want
ByteArrayInputStream mergedInputStream = new ByteArrayInputStream(baos.toByteArray());

Convert html source to pdf using iText

I have an html file, which is generated as a response by my site.
While opening the html file in my browser, all the images and other elements are displaying properly. Moreover, I want to convert this html file into a pdf file.
So am using iText API to generate the pdf file.
In the html file images and texts are located horizontally.
But in the generated pdf output the images are displaying vertically.
code
String k = convertString();
OutputStream file = new FileOutputStream(new File("f:\\Test.pdf"));
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, file);
document.open();
InputStream is = new ByteArrayInputStream(k.getBytes());
XMLWorkerHelper.getInstance().parseXHtml(writer, document, is);
document.close();
file.close();
private static String convertString() {
StringBuilder contentBuilder = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new FileReader("f://testPage.html"));
String str;
while ((str = in.readLine()) != null) {
contentBuilder.append(str);
}
in.close();
} catch (IOException e) {
}
String content = contentBuilder.toString();
return content;
}
How can I generate a pdf that looks exactly the same as the appearance of the html UI?
Also, in Jfiddle, the html page is not displaying properly. What am I missing? Is the problem with my HTML, or is there some deeper issue with Jfiddle or something else at work?

view flv video by servletvideo java

When I try to view a video in the jwplayer from a file in the webcontent directory it shows up and I can play it, but when I read the same file from a database and respond with an flv via servlet it doesn't show up. Can any one help me?
In Html file :
<script type='text/javascript' src='/ThoughRecord18-8/jwplayer.js'></script>
<script type='text/javascript'>
jwplayer('mediaspace').setup({
'flashplayer': '/ThoughRecord18-8/player.swf',
'file': '/ThoughRecord18-8/videoss?videoId=1',
'controlbar': 'bottom',
'width': '470',
'height': '320'
});
</script>
and the servlet is
String videoId = request.getParameter("videoId");
if (videoId != null || !videoId.equals("")) {
VideoDao dao = new VideoDao();
Video video = dao.getVideo(videoId);
Blob blob = video.getVideoBlob();
byte[] buf = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream in = null;
int len;
try {
len = (int) blob.length();
byte[] rb = new byte[len];
InputStream readImg = blob.getBinaryStream();
int index = readImg.read(rb, 0, len);
...
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType("video/x-flv");
response.setContentLength(rb.length);
response.setHeader("Content-Disposition", "inline; filename=file.flv");
byte[] content = new byte[DEFAULT_BUFFER_SIZE];
BufferedInputStream is = new BufferedInputStream(
new ByteArrayInputStream(rb));
OutputStream os = response.getOutputStream();
while (is.read(content) != -1) {
os.write(content);
}
is.close();
os.close();**
This isn't a java issue, JW Player only supports HTTP Psuedo Streaming and RTMP Streaming. They're both their own protocols - you can't just stream the pure content at it. Take a look at this page: http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/12534/video-delivery-http-pseudo-streaming, and this page: http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/12535/video-delivery-rtmp-streaming for info on how JW Player does streaming.
If you don't want the user to have to wait to get all of the content, you'll need to go with one of those streaming mechanisms. If that's not an issue, you could consider changing your servlet to write the file somewhere in your webcontent directory and then do a redirect to the file or something, but I don't think writing to the response stream like that is going to do the trick.

Downloadable pdf in JasperReports

I am working with JasperReprots. This is part of my code:
ServletContext context = this.getServletConfig().getServletContext();
File reportF = new File(context.getRealPath(rF));
byte[] bytes = null;
ServletOutputStream servletOutputStream = resp.getOutputStream();
InputStream reportStream = new FileInputStream(reportF.getPath());
reportF.delete();
bytes = JasperRunManager.runReportToPdf(reportStream, new HashMap(),new JREmptyDataSource());
resp.setContentType("application/pdf");
resp.setContentLength(bytes.length);
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();
After this I can see pdf in my browser, but when I try to save it, the file has no extension pdf. How to add this extension without saving report on my server?
This should probably do the trick:
resp.setHeader("Content-Disposition", "attachment;filename=report.pdf");

How to convert an <img... in html to byte [] in Java

I have opened a webpage in HtmlUnit headless browser. Now that webpage contains a image html tag as follows:
<img src="..." />
So I want that image only. But the problem is that the same src URL of the image shows diff. image each time. Means, if we refresh the img src URL, then it shows diff. image each time.
So how to get the image that is displayed on the html page.
When you get the HTMLPage, you have to get the image through one of its method. You can then get an HtmlImage, which can be saved as a file. You'll just have to analyse this file later.
This is the function to store your image with fully qualified I
protected String saveImage(String imageUrl) throws Exception {
InputStream inputStream;
OutputStream os;
ByteArrayOutputStream byteArrayOutputStream;
String destinationFile = "File path where you want ot store the image";
URL url = new URL(imageUrl);
inputStream = url.openStream();
byteArrayOutputStream = new ByteArrayOutputStream();
os = new FileOutputStream(destinationFile);
int read;
String barcode = null;
while ((read = inputStream.read()) != -1) {
os.write(read);
byteArrayOutputStream.write(read);
barcode = byteArrayOutputStream.toString();
}
inputStream.close();
os.close();
byteArrayOutputStream.close();
return barcode;
}

Categories