zoukankan      html  css  js  c++  java
  • PhantomJS 把页面转成PDF 打印

    由于项目需要把页面打印出来,本项目是用ajax动态获取表单数据的,很多数据通过浏览器打印无法实现完整信息

    于是想到爬虫,通过PhantomJS 把页面URL 抓取保存未pdf 并把流数据返给前端附件下载

    PhantomJS的安装说明这里不介绍了,pdf 保存用了PhantomJS 自带的rasterize.js 

    贴代码

    html页面  用easyui加了一个按钮

    <a href="javascript:void(0)" class="easyui-linkbutton" id="btnPdfExport" onclick="ACWS.html2Pdf()">PDF导出</a>
    

    js  把当前页面的url 和 文件名传给后端control  文件名用了页面的title

    /**
     * html 导出 pdf
     * @returns
     */
    ACWS.html2Pdf = function (){
    	var url = window.location.href;
    	var fileName = $(document).attr("title");
    	$("body").mask();
    	window.location.href = acwsContext + "/rest/pdfdownload?url="+encodeURIComponent(url)+"&fileName="+encodeURIComponent(fileName);
    	$("body").unmask();
    }
    

    control层 这里有一个问题,Process 是子进程单独处理的,但是通过process 去获取流是空的,没办法这里只有等附件生成结束后,在通过File 来获取pdf的流数据返回给前端

    /**
     * 版权所有:华信软件
     * 项目名称:gx-pms
     * 创建者: diaoby
     * 创建日期: 2019年1月5日
     * 文件说明: PhantomControl PDF 导出
     */
    package com.huaxin.gxgc.phantom.control;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import com.huaxin.acws.common.exception.AcwsGenerelException;
    import com.huaxin.acws.security.util.Security;
    import com.huaxin.acws.ucenter.model.User;
    import com.huaxin.gxgc.common.service.CommonService;
    import com.huaxin.gxgc.phantom.service.PhantomService;
    import io.swagger.annotations.Api;
    
    /**
     * @author diaoby
     * PhantomControl PDF 导出
     */
    @Api(tags = {"PhantomControl"})
    @RestController
    public class PhantomControl {
    	
    	/**
    	 * PhantomService
    	 */
    	@Resource
    	private PhantomService phantomService;
    	/**
    	 * 广西工程公用服务类
    	 */
    	@Resource
    	private CommonService commonService;
        /**
         * 关闭命令和流
         * @param process
         * @param inputStream
         * @throws IOException
         * @author diaoby
         */
        private void close(Process process, InputStream inputStream) throws  IOException {
        	if (inputStream != null) {
            	inputStream.close();
            	inputStream = null;
            }
            if (process != null) {
                process.destroy();
                process = null;
            }
        }
       
      
        /**
         * 删除PDF 临时文件
         * @param pdfPath
         * @return
         * @author diaoby
         */
        private void delPdfTempleFile(String pdfPath) {
        	File pdfFile = new File(pdfPath);
        	if(pdfFile.exists()){
        		pdfFile.delete();
        	}
        }
    	/**
    	 * html 转pdf
    	 * @param request
    	 * @return
    	 * @author diaoby
    	 * @throws UnsupportedEncodingException 
    	 * @throws InterruptedException 
    	 */
    	@RequestMapping("/pdfdownload")  
        public ResponseEntity<byte[]> html2Pdf(HttpServletRequest request,@RequestParam("url") String url,@RequestParam("fileName")String fileName) throws UnsupportedEncodingException, InterruptedException{  
        	byte[] body = null;
        	HttpHeaders headers = new HttpHeaders();    
        	fileName=new String(fileName.getBytes("UTF-8"),"iso-8859-1");
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);    
            headers.setContentDispositionFormData("attachment", fileName+".pdf");
            ResponseEntity<byte[]> responseEntity = null;
            InputStream inputStream = null ;
            Process process = null;
            FileInputStream fis = null;
            ByteArrayOutputStream bos = null;
            String filePath = phantomService.pdfTempleFilePath();
            User currentUser = Security.getCurrentUser();
            String token = commonService.getToken2(currentUser.getLoginName());
            //url 添加token 和 isPdf 参数,方便过滤页面弹出框
            url = url+"&Authorization="+token+"&isPdf=true";
            try {
            	process = phantomService.printUrlScreen2pdf(filePath,url);
                //等到 process 完成 产生pdf附件
                process.waitFor();
                //读取产生的文件到输出流
    			File pdfFile = new File(filePath);
    	    	if(pdfFile.exists()){
    	    		fis = new FileInputStream(pdfFile);
    	            bos = new ByteArrayOutputStream();
    	            byte[] b = new byte[1024];
    	            int n;
    	            while ((n = fis.read(b)) != -1)
    	            {
    	                bos.write(b, 0, n);
    	            }
    	            body = bos.toByteArray();
    	    	}
    	    	responseEntity = new ResponseEntity<byte[]>(body,headers,HttpStatus.CREATED);    
    		} catch (IOException e) {
    			throw new AcwsGenerelException("pdf导出异常", e);
    		} finally {
    			try {
    				fis.close();
    		        bos.close();
    				close(process, inputStream);
    				//删除生产的pdf文件
    				delPdfTempleFile(filePath);
    			} catch (IOException e) {
    				throw new AcwsGenerelException("pdf流关闭异常", e);
    			}
    		}
            return responseEntity;
        } 
      
    }
    

     因为系统有jwt 所以页面url都加上了token

    serivice  主要通过配置获取了phantom安装的路径和js 还有pdf存储的临时目录

    /**
     * 版权所有:华信软件
     * 项目名称:gx-pms
     * 创建者: diaoby
     * 创建日期: 2019年1月8日
     * 文件说明: Phantom service
     */
    package com.huaxin.gxgc.phantom.service;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.UUID;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    /**
     * @author diaoby
     *
     */
    @Service
    public class PhantomService {
    	/**
    	 * Phantom servie
    	 */
    	/**
    	 *  图片保存目录
    	 */
    	@Value("${phantom.pdf.tempPath}")
    	private String tempPath ;
    	/**
    	 * 空格
    	 */
        private String BLANK = " ";
        /**
         * phantomjs exe
         */
        @Value("${phantom.exe}")
        private String binPath;
        /**
         * rasterize.js
         */
        @Value("${phantom.rasterizejs}")
        private String jsPath;
        
        /**
         * 执行命令
         * @param path
         * @param url
         * @return
         * @author diaoby
         */
        public String cmd(String path, String url) {
            return binPath + BLANK + jsPath + BLANK + url + BLANK + path;
        }
        
        /**
         * 页面转pdf
         * @param url
         * @throws IOException
         * @author diaoby
         */
        public Process printUrlScreen2pdf(String pdfPath,String url) throws IOException{
            //Java中使用Runtime和Process类运行外部程序
        	String cmd = cmd(pdfPath,url);
            Process process = Runtime.getRuntime().exec(cmd);
            return process;
        }
        
        /**
         * 返回PDF 临时生产目录
         * @param url
         * @author diaoby
         */
        public String pdfTempleFilePath() {
        	return tempPath+File.separator+UUID.randomUUID().toString()+".pdf";
        }
    }
    

     下载页面

    pdf下载

  • 相关阅读:
    Postman使用教程
    CAD和ArcGIS转换 矢量配准
    SAP CRM Advanced search和Simple search里Max hit表现行为的差异
    SAP CRM Product simple search的启用步骤
    如何快速定位SAP CRM订单应用(Order Application)错误消息抛出的准确位置
    如何动态修改SAP CRM WebClient UI表格栏的宽度
    如何在SAP CRM WebClient UI里创建web service并使用ABAP消费
    如何处理SAP CRM Web Service错误
    如何使用SAP CRM WebClient UI实现一个类似新浪微博的字数统计器
    如何开启SAP CRM基于WORD模板创建附件的功能
  • 原文地址:https://www.cnblogs.com/diaobiyong/p/10245295.html
Copyright © 2011-2022 走看看