JSP导出成PDF,通过url的方式(亲测有效)
周五下午接到一个需求要通过点击选择记录,批量得到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>
用到的jar包:
链接:https://pan.baidu.com/s/1cqdGXsAvKI5PzTYh-zkxYA
提取码:7788