精华内容
下载资源
问答
  • 展开全部java生成静态页面无需特殊配置,非常简单的,下面有各种输出32313133353236313431303231363533e58685e5aeb931333332613637需求,看你要哪种就拿去用吧import javax.servlet.http.HttpServletRequest;...

    展开全部

    java生成静态页面无需特殊配置,非常简单的,下面有各种输出32313133353236313431303231363533e58685e5aeb931333332613637需求,看你要哪种就拿去用吧

    import javax.servlet.http.HttpServletRequest;

    import java.util.List;

    import java.util.ArrayList;

    import java.util.Date;

    import java.net.URL;

    import java.net.URLConnection;

    import java.io.*;

    public class JspToHtml {

    private static String title ="标题测试";

    private static String context ="标题测试";

    private static String editer ="标题测试";

    /**

    * 根据本地模板生成静态页面

    * @param JspFile jsp路经

    * @param HtmlFile html路经

    * @return

    */

    public static boolean JspToHtmlFile(String filePath, String HtmlFile) {

    String str = "";

    long beginDate = (new Date()).getTime();

    try {

    String tempStr = "";

    FileInputStream is = new FileInputStream(filePath);//读取模块文件

    BufferedReader br = new BufferedReader(new InputStreamReader(is));

    while ((tempStr = br.readLine()) != null)

    str = str + tempStr ;

    is.close();

    } catch (IOException e) {

    e.printStackTrace();

    return false;

    }

    try {

    str = str.replaceAll("###title###",

    title);

    str = str.replaceAll("###content###",

    context);

    str = str.replaceAll("###author###",

    editer);//替换掉模块中相应的地方

    File f = new File(HtmlFile);

    BufferedWriter o = new BufferedWriter(new FileWriter(f));

    o.write(str);

    o.close();

    System.out.println("共用时:" + ((new Date()).getTime() - beginDate) + "ms");

    } catch (IOException e) {

    e.printStackTrace();

    return false;

    }

    return true;

    }

    /**

    * 根据url生成静态页面

    *

    * @param u 动态文件路经 如: http://www.163.com/x.jsp

    * @param path 文件存放路经如:x:\\abc\bbb.html

    * @return

    */

    public static boolean JspToHtmlByURL(String u, String path) {

    //从utl中读取html存为str

    String str = "";

    try {

    URL url = new URL(u);

    URLConnection uc = url.openConnection();

    InputStream is = uc.getInputStream();

    BufferedReader br = new BufferedReader(new InputStreamReader(is));

    while (br.ready()) {

    str += br.readLine() + "\n";

    }

    is.close();

    //写入文件

    File f = new File(path);

    BufferedWriter o = new BufferedWriter(new FileWriter(f));

    o.write(str);

    o.close();

    str = "";

    return true;

    } catch (Exception e) {

    e.printStackTrace();

    return false;

    }

    }

    /**

    * 根据url生成静态页面

    *

    * @param url 动态文件路经 如: http://www.163.com/x.jsp

    * @return d

    */

    public static StringBuffer getHtmlTextByURL(String url) {

    //从utl中读取html存为str

    StringBuffer sb = new StringBuffer();

    try {

    URL u = new URL(url);

    URLConnection uc = u.openConnection();

    InputStream is = uc.getInputStream();

    BufferedReader br = new BufferedReader(new InputStreamReader(is));

    while (br.ready()) {

    sb.append(br.readLine() + "\n");

    }

    is.close();

    return sb;

    } catch (Exception e) {

    e.printStackTrace();

    return sb;

    }

    }

    /**

    * 测试main 函数

    *

    * @param arg

    */

    public static void main(String[] arg) {

    long begin = System.currentTimeMillis();

    //循环生成20个html文件

    for (int k = 0; k < 20; k++) {

    String url = "E:\\workspace\\oa\\golatel\\utils\\Temp\\mb.htm";//模板文件地址

    String savepath = "d:/" + k + ".html";//生成文件地址

    JspToHtmlFile(url, savepath);

    }

    System.out.println("用时:" + (System.currentTimeMillis() - begin) + "ms");

    }

    }

    //模板文件名称 leon.html

    ###title###

    cellspacing="2">

    ###title###

    作者:###author###

    ###content###

    2Q==

    已赞过

    已踩过<

    你对这个回答的评价是?

    评论

    收起

    展开全文
  • PDF技术(四)-Java实现Html转PDF文件

    万次阅读 多人点赞 2018-10-10 16:56:12
    html转换为pdf的关键技术是如何处理网页中复杂的css样式、以及中文乱码处理。 各实现对比表 于Windows平台进行测试:   基于IText 基于FlyingSaucer 基于WKHtmlToPdf ...

    html转换为pdf的关键技术是如何处理网页中复杂的css样式、以及中文乱码处理。

    各实现对比表

    于Windows平台进行测试:

     

    基于IText

    基于FlyingSaucer

    基于WKHtmlToPdf

    基于pd4ml

    跨平台性

    跨平台

    跨平台

    跨平台

    跨平台

    是否安装软件

    需安装WKHtmlToPdf

    是否收费

    免费

    免费

    免费

    收费

    转换Html

    效率

    速度快

    未测

    速度慢。相比URL来说,效率较慢。能忽略一些html语法或资源是否存在问题。

    速度快。部分CSS样式不支持。

    效果

    存在样式失真问题。

    对html语法有一定要求

    存在样式失真问题。对html语法有较高要求。

    失真情况较小

    大部分网页能按Chome浏览器显示的页面转

    部分CSS样式有问题。

    转换URL

    效率

    未测

    未测

    效率不是特别高

    未测

    效果

    未测

    未测

    部分网页由于其限制,或将出现html网页不完整。

    未测

    优点

    不需安装软件、转换速度快

    不需安装软件、转换速度快

    生成PDF质量高

    不需要安装软件、转换速度快

    缺点

    对html标签严格,少一个结束标签就会报错;

    服务器需要安装字体

    对html标签严格,少一个结束标签就会报错;

    服务器需要安装字体

     

    需要安装软件、时间效率不高

    对部分CSS样式不支持。

    评价

     

     

     

     

    综合:使用WKHtmlToPdf效果(样式)最好。但速度较慢(对于文件来说)。其余均有大大小小的失真问题。

     

     

    分页

    图片

    表格

    链接

    中文

    特殊字符

    整体样式

    速度

    IText

    支持

    支持

    支持

    支持

    支持

    支持

    失真问题

    FlyingSaucer

    未知

    未知

    未知

    未知

    未知

    未知

    未知

    WKHtmlToPdf

    支持

    支持

    支持

    支持

    支持

    支持

    很好

    pd4ml

    支持

    支持

    支持

    支持

    支持

    支持

    失真问题

    html网页完整转换为pdf,所有的方案均有不足。

    itext有时并不能满足需求,不能兼容html的样式,且从html页面导出的图片到pdf中也并不好处理。

    Flying Sauser实现html2pdf,纠错能力差,支持多种中文字体(部分样式不能识别),且对html的格式也是十分的严格,如果用一种模版的话用Flying Sauser技术倒是不错的选择,但对于不规则的html导出pdf就并不是那么的适用。

    PD4ML实现html2pdf,速度快,纠错能力强可以过滤不规则的html标记,支持多种中文字体,支持css。

    WKHtmlToPdf效果最好,但转换速度慢。

     

    1. wkhtmltopdf(速度慢、需要安装软件)

    wkhtmltopdf是一个用webkit网页渲染引擎开发的用来将html转成 pdf的工具,可跟多种脚本语言进行集成来转换文档,有windows、linux等平台版本。官网地址 http://wkhtmltopdf.org/

     

    技术特点

    Wkhtmltopdf可直接把浏览器中浏览的网页转换成一个pdf,他是一个把html页面转换成pdf的软件(需要安装在服务器上)。使用时可通过java代码调用cmd指令完成网页转换为pdf的功能。

    功能测试:

    直接在cmd里输入测试指令,可查看处理进度。

    https://images2017.cnblogs.com/blog/626790/201707/626790-20170728145110133-2123660962.png

    原理:

    使用wkhtmltopdf工具对url或html进行转换

    使用命令:

    Wkhtmltopdf  https:baidu.com  /usr/local/temp/baidu.pdf

    安装

    下载地址:https://wkhtmltopdf.org/downloads.html

    wkhtmltopdf安装方法

    1.解压wkhtmltox.tar到某个文件夹$DIR

    2.设置环境变量

    vim /etc/profile

    在最后一行加 export PATH=$DIR/wkhtmltox/bin:$PATH 保存退出、

    source /etc/profile

    3.运行 wkhtmltopdf 报wkhtmltopdf: error while loading shared libraries: libXrender.so.1: cannot open shared object file: No such file or directory这个错,请运行 apt-get/yum install libXrender*

    运行 wkhtmltopdf 报wkhtmltopdf: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory这个错,请运行apt-get/yum install libfontconfig*

    运行 wkhtmltopdf 报wkhtmltopdf: error while loading shared libraries: libXext.so.6: cannot open shared object file: No such file or directory这个错,请运行 apt-get/yum install libXext*

     

    运行 wkhtmltopdf

    yum install xorg-x11-fonts-75dpi.noarch

    yum install xorg-x11-fonts-Type1.noarch

    yum install icu.x86_64

    yum install libjpeg

    yum install libpng

     

    优点:

    支持中文、图片、CSS等

    缺点:

    有时对于html文件的转化可能比较慢,对于url的转化速度较快。存在失真情况

    具体实现:

    Java调用命令。

    public class HtmlToPdf {
    
        // wkhtmltopdf在系统中的路径
        private static String toPdfTool = Consts.WEB.CONVERSION_PLUGSTOOL_PATH_WINDOW;
    
        /**
         * html转pdf
         *
         * @param srcPath
         *            html路径,可以是硬盘上的路径,也可以是网络路径
         * @param destPath
         *            pdf保存路径
         * @return 转换成功返回true
         */
        public static boolean convert(String srcPath, String destPath) {
            File file = new File(destPath);
            File parent = file.getParentFile();
            // 如果pdf保存路径不存在,则创建路径
            if (!parent.exists()) {
                parent.mkdirs();
            }
            StringBuilder cmd = new StringBuilder();
            if (System.getProperty("os.name").indexOf("Windows") == -1) {
                // 非windows 系统
                toPdfTool = Consts.WEB.CONVERSION_PLUGSTOOL_PATH_LINUX;
            }
            cmd.append(toPdfTool);
            cmd.append(" ");
            cmd.append(" \"");
            cmd.append(srcPath);
            cmd.append("\" ");
            cmd.append(" ");
            cmd.append(destPath);
    
            System.out.println(cmd.toString());
            boolean result = true;
            try {
                Process proc = Runtime.getRuntime().exec(cmd.toString());
                HtmlToPdfInterceptor error = new HtmlToPdfInterceptor(proc.getErrorStream());
                HtmlToPdfInterceptor output = new HtmlToPdfInterceptor(proc.getInputStream());
                error.start();
                output.start();
                proc.waitFor();
            } catch (Exception e) {
                result = false;
                e.printStackTrace();
            }
    
            return result;
        }
    
        public static void main(String[] args) {
    //        HtmlToPdf.convert("http://www.baidu.com", "F:/pdf/baidu.pdf");
            String filename = "JAVA将图片转换成pdf文件-CSDN博客";
            HtmlToPdf.convert("F:/pdf/"+filename+".html", "F:/pdf/"+filename+".pdf");
    //        HtmlToPdf.convert("http://api.gyingyuan.com/", "F:/pdf/"+ UUID.randomUUID().toString()+".pdf");
    //        HtmlToPdf.convert("https://www.aliyun.com/jiaocheng/285649.html", "F:/pdf/baidu.pdf");
        }
    }
    public class HtmlToPdfInterceptor extends Thread {
        private InputStream is;
    
        public HtmlToPdfInterceptor(InputStream is){
            this.is = is;
        }
    
        @Override
        public void run(){
            try{
                InputStreamReader isr = new InputStreamReader(is, "utf-8");
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                while ((line = br.readLine()) != null) {
                    System.out.println(line.toString()); //输出内容
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

    效果:

    URL转换

     

     

    对于url转会遇到一些网站限制的问题。

    https://blog.csdn.net/m0_38138387/article/details/79314260

    如果转为html则效率较慢,但能很大程度比较完美地转换

    文件转换:速度较慢,失真情况比较小

    68.225s

     

    2. PhantomJS(样式有问题,需要安装软件)

    PhantomJS是一个基于webkit内核的无头浏览器,即没有UI界面,即它是一个浏览器,只是其内的点击、翻页等人为相关操作需要程序设计实现。它提供javaScript API接口,即通过编写JS程序可以直接与webkit内核交互,在此之上可以结合java语言等,通过java调用js等相关操作,从而解决了以前c/c++才能比较好的基于webkit开发优质采集器的限制。它同时提供windows、linux、mac等不同os的安装使用包,也就是说可以在不同平台上二次开发采集项目或是自动项目测试等工作。官网地址http://phantomjs.org/

    PhantomJS可做网页分析,功能很多,本次仅调用网页的截图功能。在cmd中的测试如下:

    https://images2017.cnblogs.com/blog/626790/201707/626790-20170728151542321-313520.png

    URL转

    测试效果并没有wkhtmltopdf好。

    html2pdf.js

    var page = require('webpage').create();
    var system = require('system');
     
    读取命令行参数,也就是js文件路径。
    if (system.args.length === 1) {
      console.log('Usage: loadspeed.js <some URL>');
    //这行代码很重要。凡是结束必须调用。否则phantomjs不会停止
      phantom.exit();
    }
    page.settings.loadImages = true;  //加载图片
    page.settings.resourceTimeout = 30000;//超过10秒放弃加载
    //截图设置,
    //page.viewportSize = {
    //  width: 1000,
    //  height: 3000
    //};
    var address = system.args[1];
    page.open(address, function(status) {
    	
    	function checkReadyState() {//等待加载完成将页面生成pdf
            setTimeout(function () {
                var readyState = page.evaluate(function () {
                    return document.readyState;
                });
     
                if ("complete" === readyState) {
                    
    				page.paperSize = { width:'297mm',height:'500mm',orientation: 'portrait',border: '1cm' };
    				var timestamp = Date.parse(new Date());
    				var pdfname = 'HT_'+timestamp + Math.floor(Math.random()*1000000);
    				var outpathstr = "E:/POMFiles/HTPDF/"+pdfname+".pdf";
    				page.render(outpathstr);
    				//page.render("c://test.png");
    				//console.log就是传输回去的内容。
    				console.log("生成成功");
    				console.log("$"+outpathstr+"$");
    				phantom.exit(); 
    				
                } else {
                    checkReadyState();
                }
            },1000);
        }
        checkReadyState();
    });
    

    PhantomJS对bootstap的样式支持较好。对css3的新特性如圆形图片样式支持行不好。部分页面样式会失效。对于echart图表展示,也可直接导出

     

     

    3. IText(技术老旧,对样式不支持)

    iText是一个第三方报表java插件,可以在后端利用java随意生成、转化pdf文件,提供了很多api,比较灵活

    IText实现html2pdf,速度快,纠错能力差,支持中文(要求HTML使用unicode编码),但中支持一种中文字体,开源。

    原理:

    使用IText将HTML文件转化为PDF文件

    优点:

    速度快,支持中文(要求HTML使用unicode编码)、开源

    缺点:

    纠错能力差,

    对CSS样式支持不是很好。

    失真情况可能比较大

    具体实现:

    <dependency>
        <groupId>org.eclipse.birt.runtime.3_7_1</groupId>
        <artifactId>com.lowagie.text</artifactId>
        <version>2.1.7</version>
    </dependency>
    <dependency>
        <groupId>org.xhtmlrenderer</groupId>
        <artifactId>flying-saucer-pdf</artifactId>
        <version>9.0.8</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.4.2</version>
    </dependency>
    

    Java代码

    ITextRenderer renderer = new ITextRenderer();
    ITextFontResolver fontResolver = renderer.getFontResolver();
    fontResolver.addFont("/Users/hehe/share/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    OutputStream os = new FileOutputStream("/Users/hehe/Desktop/iTextPDF.pdf");
    String htmlstr = HttpHandler.sendGet("http://localhost:10086/test/iTextPDF.html");//HttpHandler.sendGet只是单纯获得指定网页的html字符串内容
    renderer.setDocumentFromString(htmlstr);
    renderer.layout();
    renderer.createPDF(os);
    

    以上只是简单利用html字符串来生成pdf,需要注意的是: 
    1、如果页面中有中文,服务器端需要下载字体库simsun.ttc,在后台进行引用,同时在页面的样式中加入对应字体的定义,如:body{font-family: SimSun;},否则中文无法渲染(中文处渲染出来的效果是空白); 
    2、页面中如果有图片,如果图片引用是绝对路径或者base64则不用考虑,如果是相对路径,需要在后台用renderer.getSharedContext().setBaseURL("图片绝对路径目录");来指定图片路径,否则图片无法渲染。 
    3、要转化的页面必须是标准的XHTML页面,有一处不符合规范就会报错,小编再试的时候就经常报诸如org.xml.sax.SAXParseException;lineNumber: 24; columnNumber: 6;元素类型 "span" 必须由匹配的结束标记 "</span> 终止"之类的错误,所以如果要用iText来大量爬取网络中的页面的话,还是放弃吧,毕竟网上很多页面都是不标准的~

    public class HtmlToPdfUtils {
        /*** 默认中文字体   */
        private static final String FONT = "C:\\Windows\\Fonts\\simhei.ttf";
        public static void htmlToPdf(String sourcePath,String tagetPath) throws IOException {
            htmlToPdf(sourcePath,tagetPath,FONT);
        }
        public static void htmlToPdf(String sourcePath,String tagetPath,String fontPath) throws IOException {
            htmlToPdf(sourcePath,tagetPath,fontPath,PageSize.TABLOID);
        }
        public static void htmlToPdf(String sourcePath,String tagetPath,String fontPath,PageSize pageSize) throws IOException {
            // 默认source路径下装载有css、image、以及html等文件的文件夹
            htmlToPdf(sourcePath,tagetPath,fontPath,pageSize,FileUtils.GetFilePath(sourcePath));
        }
        public static void htmlToPdf(String sourcePath,String tagetPath,String fontPath,PageSize pageSize,String baseuri) throws IOException {
            PdfWriter writer = new PdfWriter(tagetPath);
            PdfDocument pdf = new PdfDocument(writer);
    
            pdf.setTagged();
            // 设置pdf页面大小
            pdf.setDefaultPageSize(pageSize); 
            ConverterProperties properties = new ConverterProperties();
            FontProvider fontProvider = new DefaultFontProvider();
            // 字体
            FontProgram fontProgram = FontProgramFactory.createFont(fontPath);
            fontProvider.addFont(fontProgram);
            properties.setFontProvider(fontProvider); 
            //properties.setBaseUri(html);
            properties.setBaseUri(baseuri); 
            MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.SCREEN);
            mediaDeviceDescription.setWidth(pageSize.getWidth());
            properties.setMediaDeviceDescription(mediaDeviceDescription); 
            // 转化
            convertToPdf(sourcePath,pdf, properties);
        }
    
        private static void convertToPdf(String sourcePath,PdfDocument pdf,ConverterProperties properties ) throws IOException {
            InputStream inputStream = new FileInputStream(sourcePath);
            // 转化
    //        HtmlConverter.convertToPdf(new FileInputStream(sourcePath), pdf, properties);
            HtmlConverter.convertToPdf(inputStream, pdf, properties);
            inputStream.close();
        }
        public static void main(String[] args) throws IOException {
            htmlToPdf("F:\\pdf\\1.html","F:\\pdf\\est-04.pdf");
        }
    }
    

     

    效果:

    Converting HTML to PDF _ iText Developers.html

    消耗时间:3660

    CSS样式丢失:

     

    JAVA 将图片转换成pdf文件 - CSDN博客.html

    消耗时间:7609

    样式同样丢失问题

    itext html转pdf布局问题_百度搜索.html

    消耗时间:5485

     

    4. Flying Sauser(技术老旧,对样式不支持)

    Flying Sauser实现html2pdf,纠错能力差,支持中文、支持简单的页面和样式,开源

    对html代码要求很严格。极易出现中文乱码问题

     

    优点:

    支持多种中文字体(部分样式不能识别),开源

    缺点:

    纠错能力差,对CSS支持不是很好。当页面内容较长时,处理时间慢

    具体实现:

    public class Html2Pdf {
        /**
         * HTML代码转PDF文档
         *
         * @param content 待转换的HTML代码
         * @param storagePath 保存为PDF文件的路径
         */
        public static void parsePdf(String content, String storagePath) {
            FileOutputStream os = null;
            try {
                File file = new File(storagePath);
                if(!file.exists()) {
                    file.createNewFile();
                }
                os = new FileOutputStream(file);
    
                ITextRenderer renderer = new ITextRenderer();
    //解决中文支持问题
    //            ITextFontResolver resolver = renderer.getFontResolver();
    //            resolver.addFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //            resolver.addFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                renderer.setDocumentFromString(content);
    // 解决图片的相对路径问题,图片路径必须以file开头
    // renderer.getSharedContext().setBaseURL("file:/");
                renderer.layout();
                renderer.createPDF(os);
    
            } catch (DocumentException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(null != os) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /**
         * 对Html要求特别严格
         * @param args
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
            String htmlFilePath = "";
            htmlFilePath = "F:/pdf/IText实现对PDF文档属性的基本设置 - 半亩池光 - 博客园.html";
            StringBuilder content = new StringBuilder();
            BufferedInputStream in;
            byte[] bys = new byte[1024];
            int len;
            in = new BufferedInputStream(new FileInputStream(htmlFilePath));
            while ((len = in.read(bys)) != -1) {
                content.append(new String(bys, 0, len));
            }
            String html = closeHTML(content.toString());
            html = html.replace("&nbsp;","&#160;");
    
            parsePdf(html,"F:/pdf/wahaha.pdf");
    
        }
    
        public static String closeHTML(String str){
            List arrTags = new ArrayList();
            arrTags.add("br");
            arrTags.add("hr");
            arrTags.add("link");
            arrTags.add("meta");
            arrTags.add("img");
            arrTags.add("input");
            for(int i=0;i<arrTags.size();i++){
                for(int j=0;j<str.length();){
                    int tagStart = str.indexOf("<"+arrTags.get(i),j);
                    if(tagStart>=0){
                        int tagEnd = str.indexOf(">",tagStart);
                        j = tagEnd;
                        String preCloseTag = str.substring(tagEnd-1,tagEnd);
                        if(!"/".equals(preCloseTag)){
                            String preStr = str.substring(0,tagEnd);
                            String afterStr = str.substring(tagEnd);
                            str = preStr + "/" + afterStr;
                        }
                    }else{
                        break;
                    }
                }
            }
            return str;
        }
    
    }

     

    5. PD4ML(样式有问题)

    PD4ML是纯Java的类库,使用HTMLCSS作为页面布局和内容定义格式来生成PDF文档的强大工具,可以简化最终用户生成PDF的工作。参考网站:http://www.pd4ml.com

     

    优点:

    支持中文、对html代码不严格、速度较快

    支持的HTML标签、CSS属性较全,转换失真比较小,可以使用HTML+CSS实现精确的布局控制。

    对网页文件标签、CSS语法错误的容错性比较好。

    对不用额外的控制,就支持图片的转化输出。

     

    缺点:

    存在样式失真问题,CSS支持较不好。

    不开源,最新的demo版本,下载测试以后,发现不支持中文转换。必须购买商业版本才可以。(这里很坑,测试乱码问题通不过,后面发现是本来就不支持)。

    破解后的一些旧版本可以解决乱码问题,但是支持的css样式没有新版本的全。

    具体实现:

    public class HtmlToPDFUtil {
    	public static void main(String[] args) throws Exception {
    		//HtmlToPDFUtil htmlToPDFUtil = new HtmlToPDFUtil();
    		HtmlToPDFUtil.generatePDF_2(new File("F:\\pdf/demo_ch_pd4ml.pdf"),
    				"F:\\pdf/flying saucer 使用中的一些问题 (java导出pdf) - 真的勇士,敢于直面这扯淡的人生 - ITeye博客.htm");
    
    		//File pdfFile = new File("D:/Test/test3.pdf");
    //		String pdfPath = "D:/Test1/mmt";
    //
    //		File file = new File(pdfPath);
    //		if (!file.exists()) {
    //			file.mkdirs();
    //		}
    //		String pdfName = "aa.pdf";
    //		File pdfFile = new File(pdfPath+File.separator+pdfName);
    //		StringBuffer html = new StringBuffer();
    //		html.append("<html>")
    //				.append("<head>")
    //				.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />")
    //				.append("</head>").append("<body>")
    //				//.append("<font face='KaiTi_GB2312'>")
    //				.append("<font face='KaiTi'>")
    //				.append("<font color='red' size=22>显示中文aaaaaaaaaa</font>")
    //				.append("</font>").append("</body></html>");
    //		StringReader strReader = new StringReader(html.toString());
    //		HtmlToPDFUtil.generatePDF_1(pdfFile, strReader);
    
    	}
    
    	// 手动构造HTML代码
    	public static void generatePDF_1(File outputPDFFile, StringReader strReader)
    			throws Exception {
    		FileOutputStream fos = new FileOutputStream(outputPDFFile);
    		PD4ML pd4ml = new PD4ML();
    		pd4ml.setPageInsets(new Insets(20, 10, 10, 10));
    		pd4ml.setHtmlWidth(950);
    		pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));
    		pd4ml.useTTF("java:fonts", true);		
    		//pd4ml.setDefaultTTFs("KaiTi_GB2312", "KaiTi_GB2312", "KaiTi_GB2312");
    		pd4ml.setDefaultTTFs("KaiTi", "KaiTi", "KaiTi");
    		pd4ml.enableDebugInfo();
    		pd4ml.render(strReader, fos);
    	}
    
    	// HTML代码来自于HTML文件
    	public static void generatePDF_2(File outputPDFFile, String inputHTMLFileName)
    			throws Exception {
    		FileOutputStream fos = new FileOutputStream(outputPDFFile);
    		PD4ML pd4ml = new PD4ML();
    		pd4ml.setPageInsets(new Insets(20, 10, 10, 10));
    		pd4ml.setHtmlWidth(950);
    		pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));
    
    		pd4ml.useTTF("java:fonts", true);
    		pd4ml.setDefaultTTFs("KaiTi", "KaiTi", "KaiTi");
    		pd4ml.enableDebugInfo();
    		pd4ml.render("file:" + inputHTMLFileName, fos);
    	}
    
    }
    

    pd4browser和pd4fonts是生成的

    乱码解决方案:
    https://blog.csdn.net/u014769730/article/details/54375836
    

    测试结果:

    对CSS有一定的要求

    部分Html能支持:

     

     

    6. Sferyx:(样式有问题)

    官网:https://www.sferyx.com/pdfgenerator/html-to-pdf-java.htm

    支持URL、支持文件。支持中文,对html文件几乎无要求。样式不佳,中文字体支持不佳。

    具体实现

    引入Java包:PDFGenerator.jar

    代码:

            PDFGenerator pdfGenerator=new PDFGenerator();
            pdfGenerator.setMarginsForStandardPageFormat (10,10,10,10);
    //        pdfGenerator.setCharset ("utf-8");
            pdfGenerator.setCharset("ISO-10646-UCS-2");
    //        pdfGenerator.generatePDFFromURL ("https://blog.csdn.net/gisboygogogo/article/details/77601308",
            pdfGenerator.generatePDFFromURL ("F:\\pdf\\1.html",
                    "F:\\pdf/pdfgenerator-test1.pdf",
                    "A4", "Portrait");
    

    样式问题:

     

     

    7. jPDFWriter(样式有问题、对html文件支持不好)

    具体实现:

    //        URL url = new URL("https://www.baidu.com/");
    //        PageFormat pf = new PageFormat();
    //        PDFDocument pdfDoc = PDFDocument.loadHTML (url, pf, true);
    //        pdfDoc.saveDocument ("F:\\pdf\\output.pdf");
            File f1 = new File ("F:\\pdf\\1.html");
            PDFDocument pdfDoc = PDFDocument.loadHTML(f1.toURI().toURL(), new PageFormat (), false);
            pdfDoc.saveDocument ("F:\\pdf\\output.pdf");
    

    效果:

    并不是很好,虽然支持中文

     

    其他未知方案。。。。。。。。。。

     

     

    在线转换方案:

    仅支持URL,但能很好地转换,效果较好,速度较快。但收费,且为第三方服务,或有信息安全性问题。

    如果不考虑html文件安全性的话,可以考虑。

     

    以转CSDN及百度搜索网页为测试例。

    1. restpack

    官网:https://restpack.io/                    

    能很好保持样式,且支持中文,速度快。价格相比较优惠。

    测试效果:

    实现方法:

    HttpResponse<String> response = Unirest.post("https://restpack.io/api/html2pdf/v5/convert")
      .header("x-access-token", "TOKEN")
      .body("url=http%3A%2F%2Fgoogle.com&json=true")
      .asString();

     

    2. pdfshift

    官网:https://pdfshift.io

    能很好保持样式,且支持中文,速度快。价格相比较优惠。

    测试效果:

     

    实现方法:

    String encoding = Base64.getEncoder().encodeToString("YOUR_API_KEY:".getBytes());
    HttpPost httppost = new HttpPost("https://api.pdfshift.io/v2/convert/");
    httppost.setHeader("Authorization", "Basic " + encoding);
    httppost.setHeader("Content-type", "application/json");
    
    HttpEntity postingString = new StringEntity("{\"source\":\"https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd=PhantomJS%20html%E8%BD%ACpdf&oq=PhantomJS&rsv_pq=c942451400041f65&rsv_t=3566cYExdLkZv6pJRhDXeda3WgHs37R3GASuPvnEGrOmBl9Lur2EMGyfdF8&rqlang=cn&rsv_enter=1&rsv_sug3=15&rsv_sug1=4&rsv_sug7=100&rsv_sug2=0&inputT=6104&rsv_sug4=6105\",\"landscape\":false,\"use_print\":false}");
    httppost.setEntity(postingString);
    
    CloseableHttpClient client = HttpClients.createDefault();
    try (CloseableHttpResponse response = client.execute(httppost)) {
        HttpEntity entity = response.getEntity();
        // Use the entity
    }

     

    3.其他(不考虑的方案)

    1. pdfmyurl(网站反应慢)

    官网:http://pdfmyurl.com/  

    转化效率极低,速度极其慢

     

    2. pdflayer(不支持中文)

    官网:https://pdflayer.com/

    不支持中文。虽然能很好保持样式。

     

    个人总结:

    到现在未知并为找到完美的方案。各种方案都有缺点,但是在线转换的方案转化效率以及对CSS等支持程度比较好。也不知道他们这些内部是如何实现的。
     

    参考链接:

    http://blog.csdn.net/ouyhong123/article/details/26401967

    http://blog.csdn.net/tengdazhang770960436/article/details/41320079

    http://www.cnblogs.com/jasondan/p/4108263.html

    http://blog.csdn.net/accountwcx/article/details/46785437

    http://blog.csdn.net/zdtwyjp/article/details/5769353

    展开全文
  • Java实现登录与注册页面

    万次阅读 多人点赞 2019-05-22 09:48:25
    java实现的登录与注册页面,实现了客户端(浏览器)到服务器(Tomcat)再到后端(servlet程序)数据的交互。 注册的html代码,页面非常丑!!请见谅。。 <body> <fieldset id=""> <legend>注册...

    用java实现的登录与注册页面,实现了客户端(浏览器)到服务器(Tomcat)再到后端(servlet程序)数据的交互。这里在注册页面加入了验证码验证。

    注册的html代码,页面非常丑!!请见谅。。

    <body>
    <fieldset id="">
      <legend>注册页面</legend>
      <form action="/day02/register2" method="post" id="form" ">
        <table>
          <tr>
            <td>用户名:</td>
            <td><input type="text" name="userName" /><span id="span1"></span></td>
          </tr>
          <tr>
            <td>
              密码:
            </td>
            <td>
              <input type="password" name="password" />
            </td>
          </tr>
          <tr>
            <td>
              确认密码:
            </td>
            <td>
              <input type="password" name="repassword" />
              <span id="span2"></span>
            </td>
    
          </tr>
          <tr id="tr4">
            <td>
              性别:
            </td>
            <td>
              <input type="radio" name="sex" value="男" />男
              <input type="radio" name="sex" value="女" />女
              <span id="span3"></span>
            </td>
          </tr>
          <tr>
            <td>爱好:</td>
            <td>
              <input type="checkbox" name="hobby" value="唱" />唱
              <input type="checkbox" name="hobby" value="跳" />跳
              <input type="checkbox" name="hobby" value="rap" />rap
              <input type="checkbox" name="hobby" value="篮球" />篮球
              <span id="span4"></span>
            </td>
          </tr>
          <tr>
            <td>国籍:</td>
            <td>
              <select name="country" id="country">
                <option value="none">--请选择国籍--</option>
                <option value="中国">中国</option>
                <option value="韩国">韩国</option>
                <option value="日本">日本</option>
                <option value="美国">美国</option>
              </select>
              <span id="span5"></span>
            </td>
          </tr>
          <tr>
            <td>自我评价:</td>
            <td>
              <textarea rows="10px" cols="20px" id="textarea" name="describe" ></textarea>
            </td>
          </tr>
        <tr>
            <td>
              验证码:
            </td>
            <td>
              <input type="text" name="check"/>
              <img src="/day02/demo" id="img" onclick="checkImg()" style = "cursor: pointer">
              <a href="javascript:void(0);" onclick="checkImg()">换一张</a>
            </td>
          </tr>
        </table>
        <input type="submit" id="btn2" value="提交" />
        <input type="button" id="btn1" value="验证" />
      </form>
    
    </fieldset>
    </body>
    <script type="text/javascript">
      function checkImg() {
        var img = document.getElementById("img");
        img.src ="/day02/demo?"+new Date().getTime()
    
      }
    </script>
    

    注册页面截图
    注册页面截图

    这里需要注意的是我用的是Tomcat服务器,因为它其中没有mysql驱动,所以需要手动添加到Tomcat的lib目录下。

    还有在web.xml中添加了全局配置主要是为了项目中需要改编码的方便

    <context-param>
            <param-name>encode</param-name>
            <param-value>UTF-8</param-value>
        </context-param>
    

    这里是生成验证码的程序,在我的上篇文章有详细讲解

    @WebServlet(urlPatterns = "/demo")
    public class CheckImg extends HttpServlet {
        //复写HttpServlet中的doGet方法
        public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
                IOException{
            //准备一张画纸,将验证码中的数字字母写到这张画纸中
            int width = 120;
            int height = 30;
            BufferedImage bufi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            //这里面的width、height、就是这张画纸的长宽。BufferedImage.TYPE_INT_RGB就是这张画纸基于
            //RGB三原色来进行画
            //获取一个画笔对象,给图片上画画
            Graphics2D g = (Graphics2D) bufi.getGraphics();
            //设置画笔颜色
            g.setColor(Color.WHITE);
            //将这个颜色填充到整个画纸
            g.fillRect(0,0,width,height);
            //定义图片上可以写什么数据
            String data = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";
            //定义书写在画纸上的起始位置
            int x =15;
            int y =25;
            //定义一个随机数
            Random r = new Random();
            //创建一个字符串缓冲区
            StringBuilder sb = new StringBuilder();
            //定义一个循环给画纸上写四个数
            for(int i = 0; i < 4; i++){
                //从data中随机获取一个下标的数据
                char c = data.charAt(r.nextInt(data.length()));
                sb.append(c+"");
                //随机生成画笔的颜色,RGB三原色随机在0-256中随机生成
                g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
                //设置字体
                g.setFont(new Font("黑体",Font.BOLD,26));
                double theta =(30 - (r.nextInt(60)))*Math.PI/180;
                g.rotate(theta,x,24);
                //设置数据旋转
                //g.rotate((20)*Math.PI/180,x,y);
    
                //将数据写到画纸上
                g.drawString(c+"",x,y);
                g.rotate(-theta,x,24);
                //设置完旋转要调回,防止数据旋转的看不到
                //g.rotate(-((20)*Math.PI/180),x,y);
                //每写完一个调整下一个数据写的位置
                x += 25;
            }
            HttpSession session = req.getSession();
            session.setAttribute("checkNum",sb.toString());
            //添加线类型的干扰信息
            for(int i = 0; i < 15 ; i++){
                //同样设置线的颜色
                g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
                //开始划线,这里需要的四个参数中前两个是线开头的左边,后边两个是线结束的坐标
                g.drawLine(r.nextInt(width),r.nextInt(height),r.nextInt(width),r.nextInt(height));
            }
            //添加点类型干扰信息
            for (int i = 0 ; i < 150 ; i++){
                //设置点的颜色
                g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
                //开始画点,实质上这是画椭圆,将上半轴半径,左半轴半径设置为0就可以看成是一个点
                g.drawOval(r.nextInt(width),r.nextInt(height),0,0);
            }
    
    
    
    
            //这个时候并没有在这张纸上书写任何内容,但是已经可以像客户端响应请求了
            ImageIO.write(bufi, "jpg", resp.getOutputStream());
        }
    }
    

    这是注册页面的代码。

    @WebServlet(urlPatterns = "/register2")
    public class Register extends HttpServlet {
        //
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //获取在web.xml中的配置的全局属性
            String encode = req.getServletContext().getInitParameter("encode");
            //为了防止乱码设置编码
            req.setCharacterEncoding(encode);
            resp.setContentType("text/html;charset="+encode);
            //获得请求过来的资源
            String userName = req.getParameter("userName");
            String password = req.getParameter("password");
            String repassword = req.getParameter("repassword");
            String sex = req.getParameter("sex");
            String[] hobby = req.getParameterValues("hobby");
            String country = req.getParameter("country");
            String describe = req.getParameter("describe");
            //这里将获取到的请求数据都在控制台上打印了一遍
            //看是否拿到了这些数据
            System.out.println(userName);
            System.out.println(password);
            System.out.println(repassword);
            System.out.println(sex);
            System.out.println(hobby[0]);
            System.out.println(country);
            System.out.println(describe);
            //这里只加了简单的判断,判断帐号是否填写,以及两次密码是否一致
            //判断信息是否填写
            if(userName==null||password==null||repassword==null||sex==null||hobby==null||country==null||describe==null){
                resp.getWriter().write("所有的数据都不能为空,请重新<a href = '/day02'>填写</a>");
                return;
            }
            //判断两次密码是否一致
            if(!password.equals(repassword)){
                resp.getWriter().write("两次密码输入不一致,请重新<a href = '/day02'>填写</a>");
                return;
            }
             //判断验证码输入是否正确
             if(!checkImg.equalsIgnoreCase(check)){
                resp.getWriter().write("验证码输入错误");
                return;
            }
            try {
            	//加载MySQL的数据库驱动
                Class.forName("com.mysql.jdbc.Driver");
                //这里我在数据库中添加了一个名为day02的数据库
                String url = "jdbc:mysql:///day02";
                //默认是系统管理员的账户
                String user = "root";
                //这里你自己设置的数据库密码
                String passw = "xxxxxx";
                //获取到数据库的连接
                Connection connection = DriverManager.getConnection(url, user, passw);
                //获取到执行器
                Statement stmt = connection.createStatement();
                //需要执行的sql语句
                String sql = "insert into users values (null,'"+userName+"','"+password+"','"+repassword+"','"+sex+"','"+ Arrays.toString(hobby)+"','"+country+"','"+describe+"')";
                //建议打印一下sql语句,放在数据库中看是否能将数据添加到数据库中
                System.out.println(sql);
                //执行sql语句
                int i = stmt.executeUpdate(sql);
                //添加成功上边这个执行器就会返回1
                if(i==1){
                    resp.getWriter().write("注册成功,请<a href = '/day02/login.html'>登录</a>");
                }else{
                    resp.getWriter().write("注册失败,请返回重新<a href = '/day02/'></a>");
                }
                stmt.close();
                connection.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    

    登录页面,同样非常丑。就是简单的三个input标签
    登录页面
    登录页面的html代码

    <body>
    <form action="login">
        用户名:<input type="text" name="user"><br/>
        密码:<input type="password" name="password"><br/>
        <input type="submit" name="提交">
        <a href="/register2">注册</a>
    </form>
    </body>
    

    登录页面的java代码,因为只有帐号密码,就只和数据库中的帐号密码进行判断

    @WebServlet(urlPatterns = "/login")
    public class login extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //先获取到全局配置中的设置的编码
            String encode = req.getServletContext().getInitParameter("encode");
            //设置请求和响应的编码
            req.setCharacterEncoding(encode);
            resp.setContentType("text/html;charset="+encode);
            try {
            	//从登录页面拿到用户输入的用户名
                String name = req.getParameter("user");
                //从登录页面拿到用户输入的密码
                String pwd = req.getParameter("password");
                //还是在控制台上输出看是否拿到的帐号密码
                System.out.println("用户名:" +name);
                System.out.println("密码:"+ pwd);
                //下边就是加载数据库的过程
                Class.forName("com.mysql.jdbc.Driver");
                String url = "jdbc:mysql:///day02";
                String user = "root";
                String password = "xxxxxxx";
                String sql = "select * from users where userName = '"+name+"'";
                String sql2 = "select * from users where password = '"+pwd+"'";
                Connection conn = DriverManager.getConnection(url, user, password);
                //这里我选择是创建了两个执行器,如果一个执行器执行两个sql语句。就会出现异常
         
                Statement stmt = conn.createStatement();
                Statement stmt2 =conn.createStatement();
                ResultSet rs = stmt.executeQuery(sql);
                ResultSet rs2 = stmt2.executeQuery(sql2);
                //判断用户输入的帐号是否在数据库中
                if (rs.next()){
                    System.out.print("用户名:" + rs.getString("userName") + "\t");
                }else{
                    resp.getWriter().write("对不起你帐号名有误,请<a href='/day02'>注册</a>");
                }
                //通过了帐号的判断,就对密码进行判断,同样是判断密码是否与数据库中的密码匹配
                if(rs2.next()){
                    resp.getWriter().write("登录成功,点击跳转<a href='http://www.baidu.com'>首页</a>");
                    System.out.print("密码:" + rs.getString("password") + "\t");
                }else{
                    resp.getWriter().write("对不起你密码有误,请<a href='/day02'>注册</a>");
                }
    
    
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    展开全文
  • 最终选取的方案代码细节不足之处可选方案及评价从以下三个方面考虑:页面效果还原程度是否支持复杂html/js解析中文字体显示效果JEditorPane首先找到的方案是使用java内置的Html解释工具javax.swing.JEditorPane。...

    Java图片处理:网页转图片

    需求来源于前端同事跟我反馈整天调试布局样式很难受,希望能有服务端网页转图片的方法。 记录一下研究过程。

    可选方案及评价。

    最终选取的方案

    代码细节

    不足之处

    可选方案及评价

    从以下三个方面考虑:

    页面效果还原程度

    是否支持复杂html/js解析

    中文字体显示效果

    JEditorPane

    首先找到的方案是使用java内置的Html解释工具javax.swing.JEditorPane。

    public void testHtml2Image() throws Exception

    {

    String html = "贝叶斯统计推断贝叶斯统计推断

    最大后验概率MAP

    最小均方误差LMS1.最大后验概率是在观测条件x下,寻求待估量最可能的值作为估计值,即最大后验概率时的值。

    2.最小均方误差是在观测条件x下,以待估量的均值作为估计值。";

    JEditorPane editPane = new JEditorPane("text/html", html);

    editPane.setEditable(false);

    Dimension prefSize = editPane.getPreferredSize();

    BufferedImage img = new BufferedImage(prefSize.width,prefSize.height, BufferedImage.TYPE_INT_ARGB);

    Graphics graphics = img.getGraphics();

    editPane.setSize(prefSize);

    editPane.paint(graphics);

    graphics.dispose();

    ImageIO.write(img, "png", new File("/Users/yourname/Documents/work/temp/20190219.png"));

    }

    这是最简单的HTML代码了,但显示效果却不太好,如下图所示:

    6555eb8bc8fd6049946db48287eb32be.png

    而且多尝试后发现JeditorPane解析稍微复杂一点的js页面就会出错。

    html2image

    这是百度来的,从maven上可以搜索到,下载之后发现其内部就是调用JEditorPane,只是作了简单的封装,同样不满意。

    wkhtmltox

    这是在StackOverFlow上搜索Html2Image时看到的一种方案。尝试以后,效果强于JEditorPane,考虑试用。如谷歌首页转化如下:

    最终选取方案

    wkhtmltox在三个方面均强于JEditorPane。wkhtmltox没有java版本,采用java代码调用linux命令的方式使用该工具包。

    wkhtmltox分为wkhtmltoimage 和wkhtmltopdf,经过尝试wkhtmltoimage显示效果不太好,且可调参数较少。而wkhtmltopdf转化效果相当好,因此最终解决方案:

    Created with Raphaël 2.2.0 html字符 pdf image 优化image

    其中生成pdf使用wkhtmltopdf,pdf转化image使用pdfbox(apache出品,放心使用,效果也相当好).wkhtmltopdf是将整个浏览器显示效果转为为pdf,所以对于一些没有铺满整个浏览器的网页,此时的pdf含有一部分无用的空白,应当去掉。

    先看最终效果:

    bca8912439e28faec3e4c322fac09cf1.png

    代码

    安装wkhtmltox

    在https://wkhtmltopdf.org/下载安装。linux系统可使用wget下载。

    安装成功测试命令:

    wkhtmltopdf http://google.com google.pdf

    帮助文档:

    wkhtmltopdf -H

    wkhtmltoimage -H

    代码

    命令:

    wkhtmltopdf --javascript-delay 1000 -B 0mm -L 0mm -R 0mm -T 0mm url qptest.pdf

    说明:javascript-delay是指最多等待js加载1000ms;B\L\R\T参数均是与生成的pdf文件的边距有关,可自行尝试。

    对应上面流程图的方法调用:

    html->htmlToPdf()->pdfToImage()->cutOffInvliadPart()->image

    代码实现:

    package test.java.com.action;

    import java.awt.image.BufferedImage;

    import java.io.File;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import javax.imageio.ImageIO;

    import org.apache.pdfbox.pdmodel.PDDocument;

    import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;

    import org.apache.pdfbox.rendering.PDFRenderer;

    public class HtmlToImage

    {

    public static void main(String[] args) throws Exception

    {

    Param0 param=new Param0();

    param.setDpi("2");

    param.setJavascriptDelay(1000);

    param.setUrl("https://www.google.com/");

    File pdf=htmlToPdf(param);

    File image=pdfToImage(pdf, param);

    }

    /*

    * 去掉无用的部分(pdf转成的图片有很大一部分是无用的白色背景)

    * 找出图片的有效部分,把有效部分复制到另一张新图上。

    */

    private static BufferedImage cutOffInvliadPart(BufferedImage image)

    {

    int width=image.getWidth();

    int height=image.getHeight();

    //记录原始图片每个像素的color

    int[][] rgbs=new int[width][height];

    //以下是图片有效部分的边界

    int top=height;

    int bottom=0;

    int left=-1;

    int right=-1;

    for (int i = 0; i < width; i++)

    {

    for (int j = 0; j < height; j++)

    {

    int rgb=image.getRGB(i, j);

    rgbs[i][j]=rgb;

    int tempRgb=rgb & 0x00ffffff;

    boolean isWhite=(tempRgb==0x00ffffff);

    if(!isWhite)

    {

    if(j

    {

    top = j ;

    }

    if(j>bottom)

    {

    bottom=j;

    }

    if(left==-1)

    {

    left=i;

    }

    if(i>right)

    {

    right=i;

    }

    }

    }

    }

    //留白

    bottom=(bottom+10)>(height-1)?(height-1):(bottom+10);

    left=(left>1)?(left-1):0;

    System.out.println(String.format("left:%s right:%s top:%s bottom:%s", left,right,top,bottom));

    //像素的坐标是从0算起的,所以宽高要+1.

    BufferedImage newImage = new BufferedImage(right-left+1, bottom-top+1, BufferedImage.TYPE_INT_RGB);

    for (int i = 0; i < width; i++)

    {

    for (int j = 0; j < height; j++)

    {

    if((j>=top) && (j<=bottom) && (i>=left) && (i<=right))

    {

    newImage.setRGB(i-left, j-top, rgbs[i][j]);

    }

    }

    }

    return newImage;

    }

    private static File pdfToImage(File pdf,Param0 param) throws InvalidPasswordException, IOException

    {

    String filePath=System.getProperty("java.io.tmpdir") + "/" + "test" + ".png";

    System.out.println(filePath);

    File file=new File(filePath);

    try

    {

    PDDocument pdDoc=PDDocument.load(pdf);

    PDFRenderer render=new PDFRenderer(pdDoc);

    //1=72 dpi

    BufferedImage image=render.renderImage(0,Float.parseFloat(param.getDpi()));

    BufferedImage newImage = cutOffInvliadPart(image);

    ImageIO.write(newImage, "png", new FileOutputStream(file));

    return file;

    }

    finally

    {

    //如果上传到图片服务器上则删除本地文件

    //if(file!=null && file.exists())

    //{

    //file.delete();

    //}

    if(pdf!=null && pdf.exists())

    {

    pdf.delete();

    }

    }

    }

    private static File htmlToPdf(Param0 param) throws IOException, InterruptedException

    {

    StringBuilder commandBuilder = new StringBuilder();

    if (System.getProperty("os.name").contains("Mac") || System.getProperty("os.name").contains("mac"))

    {

    //我的本地配置

    commandBuilder.append("/usr/local/bin/wkhtmltopdf");

    }

    else

    {

    //服务器配置

    commandBuilder.append("/usr/local/bin/wkhtmltopdf");

    }

    //wkhtmltopdf --javascript-delay 1000 -B 1mm -L 1mm -R 1mm -T 1mm url qptest.pdf

    commandBuilder.append(" --javascript-delay ").append(param.getJavascriptDelay() + " ")

    .append(" -B 0mm -L 0mm -R 0mm -T 0mm ");

    commandBuilder.append(param.getUrl());

    String pdfPath = System.getProperty("java.io.tmpdir") + "/" + "test" + ".pdf";

    File pdf = new File(pdfPath);

    commandBuilder.append(" " + pdfPath);

    String command = commandBuilder.toString();

    System.out.println(command);

    Process process = Runtime.getRuntime().exec(command);

    process.waitFor();

    return pdf;

    }

    /**

    * 外部传入的参数

    */

    private static class Param0

    {

    private String url;

    private String dpi="2";

    private int javascriptDelay=200;

    public String getUrl()

    {

    return url;

    }

    public void setUrl(String url)

    {

    this.url = url;

    }

    public String getDpi()

    {

    return dpi;

    }

    public void setDpi(String dpi)

    {

    this.dpi = dpi;

    }

    public int getJavascriptDelay()

    {

    return javascriptDelay;

    }

    public void setJavascriptDelay(int javascriptDelay)

    {

    this.javascriptDelay = javascriptDelay;

    }

    }

    }

    不足之处

    解决方案有以下不足:

    需要在服务器上安装wkhtmltox

    接口运行速度需要提高

    pdf转图片时只取了第一页,严谨的做法遍历以后拼到一张图上

    展开全文
  • java教学评价管理系统毕业设计答辩PPT用户登录流程图 B/S模型结构图 学生登录主界面 管理员登录主界面 教师得分 学生管理 查看评价结果 * * 教学评价系统 1 选题的背景和意义 2 研究的基本内容 3 研究的方法及措施 ...
  • 文件名称: web下载 收藏√ [5 4 3 2 1]开发工具: Java文件大小: 11802 KB上传时间: 2014-05-26下载次数: 1提 供 者: 王志凯详细说明:web课程设计源代码,包括html页面的设计和jsp后台服务的设计连接等。-web ...
  • Java Web_HTML

    2021-01-07 16:19:29
    文章目录HTML和CSSHTML1、B/S软件的结构 (Browser Server)2、前端的开发流程3、网页的组成部分4、HTML简介5、创建HTML文件6、html文件的书写规范7、HTML标签介绍8.常用标签介绍8.1 font字体标签8.2 特殊标签8.3 ...
  • 技术:HTMLJava、JSP等 摘要:当下,飞速增长的因特网用户群体迫切的需要一些新的网络技术,使他们可以在网络这个虚拟的平台上,展现自己多方面的魅力,便捷、方便的与其他网友进行沟通、互动等。不论是社区发帖、...
  • javaweb页面跳转

    2021-04-22 16:58:37
    java动态web页面,JavaWEB入门,javaweb页面跳转,javaweb页面登录他们之间的联系是什么 8 serverlet 的生命周期及各阶段的作用 9 java web两种跳转方式分别是什么有什么区别 10 include 的两种实现方式的区别 11 ...
  • 用于处理Excel电子表格的Java API无需安装Microsoft Excel,即可创建,阅读,编辑,转换,保护或打印包含10个以上文件格式的Excel电子表格。Aspose.Cells for Java是一个Excel电子表格处理API,允许Java开发人员嵌入...
  • java爬取携程酒店的评价信息以及eleven参数获取

    千次阅读 热门讨论 2018-09-27 16:13:09
    本贴已经无用了,需要爬数据的可以去携程app...访问页面https://m.ctrip.com/webapp/hotel/hoteldetail/dianping/7500321.html?&fr=detail&atime=20190510&days=1 请求地址:https://m.ctrip.com/re...
  • Java Script/Html 多种高级页面属性

    千次阅读 2016-10-11 20:45:48
    完成效果:利用java script完成多种高级页面动画。 1.图片轮播和点击换图。 代码: 图片轮播(JSP) function t1() { var img=document.getElementById("img"); img.src="../image/1.jpg"; } function ...
  • 第二步:编写登录页面(login.java)(采用纯java+servlet编写) //login.java如下 package cn.hnu; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import ...
  • *^_^*今天和一个朋友共同完成了一个基于java的学生日常评分管理系统项目,我们在开发时选用的框架是SSM(MYECLIPSE)框架。我这个朋友知识有限,只会这个框架,哈哈,都是为了方便他。和往常一样选用简单又便捷的...
  • 可能导致页面中所有元素都浮动 父元素脱离了标准流 改变了元素的盒子特性(不推荐) 代码:清浮动-02 让父元素成为绝对定位元素(position 设置为 absolute 或 fixed) 父元素脱离了标准流 改变了元素的盒子特性(不...
  • 1、需求及配置需求:爬取京东手机搜索页面的信息,记录各手机的名称,价格,评论数等,形成一个可用于实际分析的数据表格。使用maven项目,log4j记录日志,日志仅导出到控制台。maven依赖如下(pom.xml)?log4j配置...
  • 接着上一篇的写,本篇记录的是从jsp页面传值到java后台的方法中,当后台获取到了页面上的值才可以进行新增和修改的相关操作。  最为常见的就是表单提交,表单提交又分为submit和button两种不同的方式 无标题...
  • //将缓冲区的输入输出到页面 in.read(b); } sout.flush(); //输入完毕,清除缓冲 sout.close(); } %> 将此文件保存为testimageout.jsp文件。下一步要做的工作就是使用HTML标记: <%@ page contentType="text/html;...
  • 展开全部这个在做网页中常e69da5e887aa62616964757a686964616f31333339666636要用到,有些通用的内容可集中放在一个页面文件中,其它要用到这些内容的页面只需要包含(引用)这个通用文件即可。这样便于维护,如果有很...
  • 内容(结构):在页面中可以看到的数据,一般通过html技术来展示 表现:内容在页面上的展现形式,比如说布局、颜色、大小等,一般使用css技术实现 行为:页面中元素与输入设备交互的响应,一般使用javascript技术实现 ...
  • html用户注册页面

    2021-07-24 17:54:55
    html用户注册界面 ** <body> <!-- form 标签是表单标签 action 属性设置提交的服务器地址 method 属性设置提交的方式 GET(默认值)或 POST 表单提交的时候,数据没有发送给服务器的三种情况: 1、表单项没有...
  • 自我评价(案例一)1、熟悉W3C规范,能熟练编写优雅的HTML+CSS代码,包括H5和C3新特性,熟练解决低版本浏览器兼容问题。2、熟练操作JavaScript,能够运用面向对象编程思想进行编程,熟悉ES5/ES6语法。3、熟练掌握Ajax...
  • 首先,将如下代码加入主页面HTML的区: 然后,用(注意不是openwin而是loadpop啊!)替换主页面中原有的这一句即可。你可以试着刷新一下这个页面或重新进入该页面,窗口再也不会弹出了。真正的Pop-Only-Once!
  • 其实就和我们平时在页面中保存一些信息是一样的,通过隐藏字段来保存,保存的形式如: 〈input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae"〉,...
  • 先建立一个模本页面:template.htm###title######title###作者:###author######content###=========================================再写一个JSP页面: buildhtml.jsptry{String title="jsp生成静态html文件";...
  • 手把手教你用Java设计并实现一个城市公交查询系统

    千次阅读 多人点赞 2020-12-19 10:11:33
    为了使得我国公交乘客出行及查询有关信息更方便,本文运用JAVA语言技术,Jsp技术,Mysql数据库开发了B/S结构的城市公交查询系统。 该系统顺应了时代发展且具有以下优点:首先,方便乘客的出行,乘客不用询问站牌工作...
  • 一个html表单页面

    千次阅读 2020-04-17 18:18:36
    DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>标题</title> </head> <body> <!--表单是html界面收集用户信息,并最后发送给服务器--&...
  • 展开全部想做分e69da5e887aa62616964757a...给你一个我写的程序前台页面:module_js =function() {var ds, cm, gridHead, gridFoot, paging, grid;var countPerPage=12; //每页显示几条var mod_module_win,mod...
  • JAVA面试汇总

    千次阅读 2018-08-14 15:01:42
    2017年美团Java程序员开发 热乎的面经,昨天面的美团,虽然面完了HR面,但是感觉希望不大,希望能走运拿到offer吧。三面技术面面经如下: 一面: 中间省略掉大概几个问题,因为我不记得了,下面记得的基本都是我...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,632
精华内容 5,052
关键字:

java评价页面html

java 订阅