周五下午接到一个需求要通过点击选择记录,批量得到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