很久以前使用itext转换html到pdf过,但当时没记录,最近又有这种需求,一直没想起来,现在做好了记录一下
下面是伪代码:
依赖jar包及版本:
注意事项:
1.html标签必须成对,有对应的结束标签,比如或
2.在样式表中第一行加入@page{size:200mm 300mm;} 可以设置PDF宽高
3.该版本不支持CSS3,所以页面中如果有CSS3的样式写法,可能需要修改成CSS2
4.html中必须设置中文字体样式,否则中文无法正常显示,比如:
,且字体样式必须与下面代码中设置的一致,比如使用了C:/Windows/Fonts/simsun.ttc,则此处必须使用SimSun(区分大小写)-Html2Pdf.java-----------------------------------------------------------------------------------------------------------------------
OutputStream os = new FileOutputStream("PDF文件输出全路径");
ITextRenderer renderer = new ITextRenderer();
// 图片base64支持,把图片转换为itext自己的图片对象
if(hasImage) {// 如果携带图片则加上以下代码,将图片标签转换为Itext自己的图片对象
renderer.getSharedContext().setReplacedElementFactory(new Base64ImgReplacedElementFactory());
renderer.getSharedContext().getTextRenderer().setSmoothingThreshold(0);
}
renderer.setDocumentFromString(html);
// 解决中文支持问题
ITextFontResolver fontResolver = renderer.getFontResolver();
// 字体设置,字体文件路径比如可以为C:/Windows/Fonts/simsun.ttc,也可以拷贝到其他目录
fontResolver.addFont("字体文件路径", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
// renderer.getSharedContext().setBaseURL("file:/D:/z/temp/"); // 如果img标签中src是http或绝对地址可以不要本行代码,另外对于linux系统中写法暂不确认应该是不需要file:/前缀
renderer.layout();
renderer.createPDF(os);
os.close();
Base64ImgReplacedElementFactory.java:----------------------------------------------------------------------------------
import java.io.IOException;
import org.w3c.dom.Element;
import org.xhtmlrenderer.extend.FSImage;
import org.xhtmlrenderer.extend.ReplacedElement;
import org.xhtmlrenderer.extend.ReplacedElementFactory;
import org.xhtmlrenderer.extend.UserAgentCallback;
import org.xhtmlrenderer.layout.LayoutContext;
import org.xhtmlrenderer.pdf.ITextFSImage;
import org.xhtmlrenderer.pdf.ITextImageElement;
import org.xhtmlrenderer.render.BlockBox;
import org.xhtmlrenderer.simple.extend.FormSubmissionListener;
import com.lowagie.text.BadElementException;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.codec.Base64;
/**
* 图片base64支持,把图片转换为itext自己的图片对象
* @author Administrator
*
*/
public class Base64ImgReplacedElementFactory implements ReplacedElementFactory {
/**
* 实现createReplacedElement 替换html中的Img标签
*
* @param c 上下文
* @param box 盒子
* @param uac 回调
* @param cssWidth css宽
* @param cssHeight css高
* @return ReplacedElement
*/
public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, UserAgentCallback uac,
int cssWidth, int cssHeight) {
Element e = box.getElement();
if (e == null) {
return null;
}
String nodeName = e.getNodeName();
// 找到img标签
if (nodeName.equals("img")) {
String attribute = e.getAttribute("src");
FSImage fsImage;
try {
// 生成itext图像
fsImage = buildImage(attribute, uac);
} catch (BadElementException e1) {
fsImage = null;
} catch (IOException e1) {
fsImage = null;
}
if (fsImage != null) {
// 对图像进行缩放
if (cssWidth != -1 || cssHeight != -1) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
}
return null;
}
/**
* 编解码base64并生成itext图像
*/
protected FSImage buildImage(String srcAttr, UserAgentCallback uac) throws IOException,
BadElementException {
FSImage fiImg=null;
if (srcAttr.toLowerCase().startsWith("data:image/")) {
String base64Code= srcAttr.substring(srcAttr.indexOf("base64,") + "base64,".length(),
srcAttr.length());
// 解码
byte[] decodedBytes = Base64.decode(base64Code);
fiImg= new ITextFSImage(Image.getInstance(decodedBytes));
} else {
fiImg= uac.getImageResource(srcAttr).getImage();
}
return fiImg;
}
public void reset() {}
@Override
public void remove(Element arg0) {}
@Override
public void setFormSubmissionListener(FormSubmissionListener arg0) {}
}
----------------------------------------------------------------------------------