带<img>标签的html转pdf,输出到浏览器
【代码】带标签的html转pdf,输出到浏览器。
·
思路
- 若html不是工整的,先将html格式化一下(jsoup),若html是文件则直接引入
- 将标签里面的src替换成绝对路径
- 将html转成pdf(itext)
- 再将pdf转jpg(pdfbox)
- 将jpg输出到浏览器
html格式化(jsoup)
- 因为我的HTML代码是从数据库里面取的,所以不是工整的,先格式化一下
- 引入jsoup
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.3</version>
</dependency>
- 格式化的代码
//str是HTML的字符串,返回的docHtml是格式化之后的
//一定要这样写不要直接
Document document= Jsoup.parse(str,"utf-8");
Document.OutputSettings setting=new Document.OutputSettings();
setting.syntax(Document.OutputSettings.Syntax.xml);
Document doc = document.outputSettings(setting);
String docHtml = doc.outerHtml();
替换标签的路径
- 我的需求里面里面的路径是相对路径,我需要换成绝对路径
//我这里的sysParam是图片路径的前缀
String docHtmlImg = docHtml .replaceAll("<img src=\"", "<img src=\"" + sysParam);
将HTML转成PDF(itext)
- 引入iText
<!--用itext将html转成pdf-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.5</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
- HTML转PDF的代码
- 注意生成的PDF要先创建好相关路径
//第一步,创建一个 iTextSharp.text.Document对象的实例:
com.itextpdf.text.Document docu = new com.itextpdf.text.Document();
//第二步,为该Document创建一个Writer实例:
PdfWriter writer = null;
try {
writer = PdfWriter.getInstance(docu, new FileOutputStream("D:\\test\\HelloWorld.pdf"));
} catch (DocumentException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
//第三步,打开当前Document
docu.open();
}
//第四步,为当前Document添加内容:
// 4.1 该为加载html文件字符串生成pdf方式,直接从文件你取html代码
// File file2 = ResourceUtils.getFile("D:\\test\\HelloWorld.html");
// String s = FileReader.create(file2).readString();
//用Jsoup格式化html文字
Document document= Jsoup.parse(str,"utf-8");
Document.OutputSettings setting=new Document.OutputSettings();
setting.syntax(Document.OutputSettings.Syntax.xml);
Document doc = document.outputSettings(setting);
String docHtml = doc.outerHtml();
log.info(docHtml);
ByteArrayInputStream fis = new ByteArrayInputStream(docHtml.getBytes());
// 4.2 该为加载html文件生成pdf方式
//FileInputStream fis = new FileInputStream("D:\\test\\HelloWorld.html");
try {
//这里的FontProviderUtil重写了字体
XMLWorkerHelper.getInstance().parseXHtml(writer, docu,fis ,null, Charset.defaultCharset(),new FontProviderUtil());
//第五步,关闭Document
} catch (IOException e) {
e.printStackTrace();
}
docu.close();
log.info("生成PDF成功!");
public class FontProviderUtil extends XMLWorkerFontProvider {
@Override
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("STSongStd-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;
}
}
- 生成了D:\test\HelloWorld.pdf
将pdf转jpg(pdfbox)
- 引入pdfbox
<!--pdf转jpg-->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.26</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.26</version>
</dependency>
- PDF转JPG的代码
@Slf4j
public class PdfUtil {
public static final int DEFAULT_DPI = 150;
/**
* pdf转图片
* 多页PDF会每页转换为一张图片,下面会有多页组合成一页的方法
*
* @param pdfFile pdf文件路径
* @param outPath 图片输出路径
* @param dpi 相当于图片的分辨率,值越大越清晰,但是转换时间变长
*/
public static void pdf2multiImage(String pdfFile, String outPath, int dpi) throws IOException, DocumentException {
if (ObjectUtil.isEmpty(dpi)) {
// 如果没有设置DPI,默认设置为150
dpi = DEFAULT_DPI;
}
try (PDDocument pdf = PDDocument.load(new FileInputStream(pdfFile))) {
int actSize = pdf.getNumberOfPages();
List<BufferedImage> picList = Lists.newArrayList();
for (int i = 0; i < actSize; i++) {
BufferedImage image = new PDFRenderer(pdf).renderImageWithDPI(i, dpi, ImageType.RGB);
picList.add(image);
}
// 组合图片
yPic(picList, outPath);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 将宽度相同的图片,竖向追加在一起 ##注意:宽度必须相同
*
* @param picList 文件流数组
* @param outPath 输出路径
*/
public static void yPic(List<BufferedImage> picList, String outPath) {// 纵向处理图片
if (picList == null || picList.size() <= 0) {
log.info("图片数组为空!");
return;
}
try {
// 总高度
int height = 0,
// 总宽度
width = 0,
// 临时的高度 , 或保存偏移高度
offsetHeight = 0,
// 临时的高度,主要保存每个高度
tmpHeight = 0,
// 图片的数量
picNum = picList.size();
// 保存每个文件的高度
int[] heightArray = new int[picNum];
// 保存图片流
BufferedImage buffer = null;
// 保存所有的图片的RGB
List<int[]> imgRgb = new ArrayList<int[]>();
// 保存一张图片中的RGB数据
int[] tmpImgRgb;
for (int i = 0; i < picNum; i++) {
buffer = picList.get(i);
// 图片高度
heightArray[i] = offsetHeight = buffer.getHeight();
if (i == 0) {
// 图片宽度
width = buffer.getWidth();
}
// 获取总高度
height += offsetHeight;
// 从图片中读取RGB
tmpImgRgb = new int[width * offsetHeight];
tmpImgRgb = buffer.getRGB(0, 0, width, offsetHeight, tmpImgRgb, 0, width);
imgRgb.add(tmpImgRgb);
}
// 设置偏移高度为0
offsetHeight = 0;
// 生成新图片
BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < picNum; i++) {
tmpHeight = heightArray[i];
if (i != 0) {
// 计算偏移高度
offsetHeight += tmpHeight;
}
// 写入流中
imageResult.setRGB(0, offsetHeight, width, tmpHeight, imgRgb.get(i), 0, width);
}
File outFile = new File(outPath);
// 写图片
ImageIO.write(imageResult, "png", outFile);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException, DocumentException {
PdfUtil.pdf2multiImage("D:/file/1.pdf","D:/file/1.jpg",150);
}
}
- 这里转JPG可能会中文乱码,出现方块等问题
- 日志会出现下面的语句
- 这个语句的意思是系统没有安装STSong-Light字体,pdfbox使用STSongStd-Light-Acro字体来替代了
- 看看你的日志里面是什么字体替代了STSong-Light字体(博主找到的STSong-Light字体都不能用,所以就找了STSongStd-Light-Acro字体,有找到的可以留言,STSongStd-Light-Acro字体的链接放下面了)
将jpg输出到浏览器
FileInputStream fis = new FileInputStream(new File(jpgSource));
response.setContentType("image/png");
fis.getChannel().transferTo(0, fis.available(), Channels.newChannel(response.getOutputStream()));
return null;
- 字体的链接:https://www.fontke.com/font/26348617/
更多推荐
已为社区贡献2条内容
所有评论(0)