Generating pdf with wkhtmltopdf and download the pdf

Ranjan

I am working in a old project.The project is in Spring MVC .In the project I have to generate a pdf file from a jsp page and store in a location and download that file. For that I am using wkhtmltopdf tool to convert the one specific jsp page into pdf format. Using wkhtmltopdf sometime works fine, it generate the pdf in specific location, but sometime it require more time. Also when I am trying to download the file from specific location , sometime it download a 0KB size file or sometime the downloaded file can't be open (with some size) but sometime download perfectly. If I check the file at define location, it exist and open normally. Here is my code in controller class.

@RequestMapping(value="/dwn.htm",method=RequestMethod.GET)
public void dwAppFm(HttpSession session,HttpServletRequest request,HttpServletResponse response,@RequestParam String id) throws IOException,InterruptedException
{           
         final int BUFFER_SIZES=4096;
         ServletContext context=request.getServletContext();             
         String savePath="/tmp/";//PDF file Generate Path
         String fileName="PDFFileName"; //Pdf file name
         FileInputStream inputStream=null;
         BufferedInputStream bufferedInputStream=null;
         OutputStream outputStream=null;
             printApp(id,fileName);
         Thread.sleep(1000);
         printApp(id,fileName);         
         File download=new File(savePath+fileName+".pdf");
         while(!download.canRead())
           {
                Thread.sleep(1000);
            printApp(id,fileName);
            download=new File(savePath+fileName+".pdf");                                    
           }

       if(download.canRead()){//if the file can read
        try{
            Thread.sleep(1000);
            inputStream=new FileInputStream(download);
                bufferedInputStream=new BufferedInputStream(inputStream);
            String mimeType = context.getMimeType(savePath+fileName+".pdf");
            if (mimeType == null) {                 
                mimeType = "application/octet-stream";
            }
            System.out.println("MIME type: " + mimeType);
            response.setContentType(mimeType);
            response.setContentLength((int)download.length());              
            String headerKey="Content-Disposition";
            String headerValue=String.format("attachment;filename=\"%s\"", download.getName());
            response.setHeader(headerKey, headerValue);             
            outputStream=response.getOutputStream();
            byte[] buffer=new byte[BUFFER_SIZES];
            int bytesRead=-1;

            while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }           


        }catch(Exception e)
        {               
            e.printStackTrace();

        }

        finally
        {
            try{                    
                if(inputStream!=null)inputStream.close();
                if(bufferedInputStream!=null)bufferedInputStream.close();
                if(outputStream!=null)outputStream.close();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
       }    

}

public void printApp(String id,String fileName)
{
    try{
        String urlPath="http://localhost:8080/proj";
        urlPath+="/genApp.htm?id="+id;//generate url to execute wkhtmltopdf 
        String wxpath="/home/exm/wkhtmltopdf";//the path where wkhtmltopdf located  
        String save="/tmp/"+fileName+".pdf";//File save Pathname
        Process process=null;
        process=Runtime.getRuntime().exec(wxpath+" "+urlPath+" "+save);     
        }catch(Exception e)
        {}
}

@RequestMapping(value="/genApp.htm",method=RequestMethod.GET)
public String getApplicationPDF(HttpServletRequest request,HttpSession session,@RequestParam String id)
{   
    UDets uDets=uService.getAllById(Long.parseLong(id));//Methods to get details
    request.setAttribute("uDets",uDets );   
    return "makeApp";//Name of the jsp page
}

In my code I have use Thread.sleep(1000) and printApp(id,fileName) method three times , since sometime wkhtmltopdf fail to generate pdf in certain time and then probability of downloading 0KB file is more. I haven't share the jsp page since the jsp page contain simple jsp page code of lots of line (the size of the generated pdf file is two page).

So the problem is what should I change in my code so that the pdf file generated and download without a failure also in heavy load in server.

If there is any best procedure or idea please share.

I don't like to use itext, since the jsp page contain complex design. Any advise is also appreciable and also thanks in advance.

M. Deinum

I would say that your code is flawed not just a little but big time. You are checking if a file can be read, if not you start again a proces writing to the same file (at least twice). At some time you will endup with multiple processes trying to write to the same file, resulting in strange behavior.

I would refactor the printApp method to return the Process it created. Then call waitFor on that process. If it returns 0 and doesn't get interrupted it completed successfully and you should be able to download the file.

@RequestMapping(value="/dwn.htm",method=RequestMethod.GET)
public void dwAppFm(HttpSession session,HttpServletRequest request,HttpServletResponse response,@RequestParam String id) throws IOException,InterruptedException
{           
         String savePath="/tmp/";//PDF file Generate Path
         String fileName="PDFFileName.pdf"; //Pdf file name
         File download = new File(savePath, fileName);

         try {
           Process process = printApp(id, download.getPath());
           int status = process.waitFor();
           if (status == 0) {
             response.setContentType("application/pdf");
             response.setContentLength((int)download.length());              
             String headerKey="Content-Disposition";
             String headerValue=String.format("attachment;filename=\"%s\"", download.getName());
             StreamUtils.copy(new FileInputStream(download), response.getOutputStream())
           } else {
             // do something if it fails.
           }

         } catch (IOException ioe) {
           // Do something to handle exception
         } catch (InterruptedException ie) {
           // Do something to handle exception
         }

       }    

}

public Process printApp(String id, String pdf) throws IOException {    
        String urlPath="http://localhost:8080/proj";
        urlPath+="/genApp.htm?id="+id;//generate url to execute wkhtmltopdf 
        String wxpath="/home/exm/wkhtmltopdf";//the path where wkhtmltopdf located  
        String command = wxpath+" "+urlPath+" "+pdf;        
        return Runtime.getRuntime().exec(command);     
}

Something like the code above should to the trick.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Generating pdf with wkhtmltopdf Django

From Dev

Generating pdf with wkhtmltopdf Django

From Dev

Java Pdf Generating and Download

From Dev

wkhtmltopdf error when generating pdf with lots of pages with header / footer

From Dev

Local datetime when generating PDF using wkhtmltopdf library

From Dev

PDF generation error with wkhtmltopdf

From Dev

wkhtmltopdf pdf differences

From Dev

wkhtmltopdf: Is it possible to merge PDF files?

From Dev

How to get pdf created with PHP WkHtmlToPdf to download with slim 3 without encoding breaking

From Dev

Generating a probability from a pdf?

From Dev

generating Persian PDF with iText

From Dev

Generating pdf in Angular 2

From Dev

Generating PDF File

From Dev

Generating a PDF from images

From Dev

generating bookmarks for pdf

From Dev

In Live Server (Windows server 2008 R2 enterprise) PDF Is Not Generating with wkhtmltopdf.exe, but works in Local Host

From Dev

Generating Reports with Python: PDF or HTML to PDF

From Dev

wicked_pdf on Rails 4 not generating pdf

From Dev

Creating Landscape PDF using WkHtmlToPdf by Mikehaertl

From Dev

node wkhtmltopdf create corrupted PDF in node webkit

From Dev

WKHTMLtoPDF header file content not displayed in PDF

From Dev

convert html into pdf using wkhtmltopdf in nodejs

From Dev

Can not print pdf using wkhtmltopdf on mac

From Dev

Wkhtmltopdf tiny pdf when content is long

From Dev

Creating Landscape PDF using WkHtmlToPdf by Mikehaertl

From Dev

convert html into pdf using wkhtmltopdf in nodejs

From Dev

node wkhtmltopdf create corrupted PDF in node webkit

From Dev

Can not print pdf using wkhtmltopdf on mac

From Dev

Background Image not showing in PDF using WKHTMLTOPDF

Related Related

HotTag

Archive