JSP导出成PDF,通过url的方式(亲测有效)

2 篇文章 0 订阅
2 篇文章 0 订阅

周五下午接到一个需求要通过点击选择记录,批量得到pdf的压缩包

先搞好JSP转PDF

我是通过访问的返回视图,url来实现转成pdf,全程通过输入输出流,用的是itexpdf,不过图片无法转,只能通过手动插入。

上测试代码:

 

Controller层:

import com.itextpdf.text.DocumentException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

@RestController
@RequestMapping("/download")
public class downServlet {
    
    @RequestMapping("/test2")
    public void print(HttpServletRequest request, HttpServletResponse response) throws IOException, DocumentException {
        String url = "http://localhost:8080/zyerp_adp_war/zy/zyProjectInfo/zyOpenProFinishPrint/0/32854";
        String  result = CreatePdfDocument.parseURL2PDFFile(url);
        // 设置输出的格式
        result = java.net.URLDecoder.decode(result, "ISO-8859-1");//如果跨域需设置解码
        ByteArrayInputStream inStream = new ByteArrayInputStream(
                result.getBytes("ISO-8859-1"));
        // 设置输出的格式
        response.setContentType("bin");
        response.addHeader("Content-Disposition","attachment; filename=\"" +"test"+ ".pdf\"");
        InputStream inputStream = inStream;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ByteArrayInputStream inputStreamAll = ImageWordUtil.add(inputStream,bos);
        // 循环取出流中的数据
        byte[] b = new byte[2048];
        int len;
        try {
            while ((len = inputStreamAll.read(b)) > 0)
                response.getOutputStream().write(b, 0, len);
            inputStream.close();
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

 

工具类:

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import org.jsoup.Jsoup;

import java.io.*;

public class PdfDocumentUtils {

    /**
     * 根据URL提前blog的基本信息,返回结果
     * @param url
     * @return
     * @throws Exception
     */
    public static  String[] extractHtmlInfo(String url) throws Exception {
        /*这里为什么用数组,是因为返回的时候不仅可以返回选择的html,
        还有从document提取其他的信息单独存在数组里返回,然后利用iText在pdf里面组装数据,可以在网上查*/
        String[] info = new String[1];
        // 直接把URL解析成document,然后调用document.html()解析为html
        org.jsoup.nodes.Document doc = Jsoup.connect(url).get();
        // 此doc.select是用来选择完整的html中某一部分这里为第一个div的css为entry的部分,所以你的html上要有div的class为entry哦
        org.jsoup.nodes.Element entry = doc.select("div.entry").first();
        info[0] = entry.html();
        return info;
    }

    /**
     * 直接通过得到html来取得想要的部分html
     * @param html
     * @return
     * @throws Exception
     */
    public static  String[] extractHtmlInfo2(String html) throws Exception {
        String[] info = new String[1];
        // 把html转换为document
        org.jsoup.nodes.Document doc = Jsoup.parse(html);
        // 此doc.select是用来选择完整的html中某一部分这里为第一个div的css为entry的部分,所以你的html上要有div的class为entry哦
        org.jsoup.nodes.Element entry = doc.select("div.entry").first();
        info[0] = entry.html();
        return info;
    }

    /**
     * 把String 转为 InputStream
     * @param content
     * @return
     */
    public static InputStream parse2Stream(String content) {
        try {
            ByteArrayInputStream stream = new ByteArrayInputStream(
                    content.getBytes("UTF-8"));
            return stream;
        } catch (Exception e) {

            return null;
        }
    }


    /**
     * 直接把网页内容转为PDF文件
     *
     * @param
     * @throws Exception
     */
    public static String parseURL2PDFFile(String html) {
        String result = "";
        ByteArrayOutputStream baos = null;
        Document doc = null;

        try {
            BaseFont bfCN = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H",
                    false);
            // 中文字体定义
            Font chFont = new Font(bfCN, 14, Font.NORMAL, BaseColor.BLUE);
            Font secFont = new Font(bfCN, 12, Font.NORMAL, new BaseColor(0, 204,
                    255));
            Font textFont = new Font(bfCN, 12, Font.NORMAL, BaseColor.BLACK);

//            PdfPTable table = new PdfPTable(3);

//            Document document = new Document(PageSize.A4);

            // 设置pdf的背景图片
//            Image image = Image.getInstance("D:/移动背景图片.jpg");
//            image.setAlignment(image.UNDERLYING);
//            image.setAbsolutePosition(0,0);
//            image.scaleAbsolute(595,842);

            Rectangle rectPageSize = new Rectangle(PageSize.A4);
            doc = new Document(rectPageSize);// 可配其余4个参数,如(rectPageSize,60,60,60,60)页面边距

            baos = new ByteArrayOutputStream();//构建字节输出流
            PdfWriter pdfWriter = PdfWriter.getInstance(doc, baos);//将PDF文档对象写入到流
            pdfWriter.setViewerPreferences(PdfWriter.HideToolbar);

            doc.open();

//            document.open();
//            document.add(image);
            //得到解析的html
            String[] blogInfo = extractHtmlInfo(html);

        /*html文件转换为pdf文档
        AsianFontProvider()函数是用来解决XMLWorkerHelper.getInstance().parseXHtml()转pdf中文不显示问题*/
            XMLWorkerHelper.getInstance().parseXHtml(pdfWriter,doc,parse2Stream(blogInfo[0]), (InputStream) null, new AsianFontProvider());

            if (doc != null) {
                doc.close();
            }
            result = new String(baos.toByteArray(), "ISO-8859-1");//转字符串设置编码
            result = java.net.URLEncoder.encode(result, "ISO-8859-1");//如果跨域需设置编码
        } catch (Exception e) {

            e.printStackTrace();
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

        }
        return result;
    }

}

 

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

import java.io.*;

public class ImageWordUtil {
    /**
     * pdf添加完工转账格式的图片和文字
     * @param filePath
     * @throws IOException
     * @throws DocumentException
     */
    public static ByteArrayInputStream add(InputStream input, ByteArrayOutputStream output) throws IOException, DocumentException {
        BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
        PdfReader reader = new PdfReader(input);
        PdfStamper stamper = new PdfStamper(reader, output);
        PdfContentByte page = stamper.getOverContent(1);

        //将文字贴入pdf
        page.beginText();
        page.setFontAndSize(baseFont,10);
        BaseColor coler = new BaseColor(0, 0, 0);
        page.setColorFill(coler);
        page.setTextMatrix(470,800); //设置文字在页面中的坐标
        page.showText("上海中移信息技术有限公司");
        page.endText();


        //将图片贴入pdf
        Image image = Image.getInstance("E:\\pdf\\yz_logo.png");
        image.scaleToFit(137, 35);
        image.setAbsolutePosition(0, 780); //设置图片在页面中的坐标
        page.addImage(image);
        stamper.close();
        reader.close();
        input.close();
        ByteArrayInputStream inputStream = new ByteArrayInputStream(output.toByteArray());
        return inputStream;
    }
}

 

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;

/*
 * 用来解决XMLWorkerHelper.getInstance().parseXHtml()转pdf中文不显示问题
 */
public class AsianFontProvider extends XMLWorkerFontProvider{

    public Font getFont(final String fontname, final String encoding,
                        final boolean embedded, final float size, final int style,
                        final BaseColor color) {
        BaseFont bf = null;
        try {
            bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Font font = new Font(bf, size, style, color);
        font.setColor(color);
        return font;
    }
}

用到的依赖包:

<dependency>
    <groupId>com.itextpdf.tool</groupId>
    <artifactId>xmlworker</artifactId>
    <version>5.5.9</version>
</dependency>
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.10.3</version>
</dependency>

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.9</version>
</dependency>

参考地址:https://blog.csdn.net/zhangyongbink/article/details/86063794?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159581942419725222400586%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159581942419725222400586&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v3~pc_rank_v2-2-86063794.first_rank_ecpm_v3_pc_rank_v2&utm_term=extractHtmlInfo&spm=1018.2118.3001.4187

 

用到的jar包:

链接:https://pan.baidu.com/s/1cqdGXsAvKI5PzTYh-zkxYA 
提取码:7788

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值