该文章的为传递一整套html内容,后台转为pdf的方法,有一个小问题是(html里写的图片无法生成出来。。不知道为啥)
1、先引入jar包
com.itextpdf.tool
xmlworker
5.5.1
com.itextpdf
itext-asian
5.2.0
org.xhtmlrenderer
flying-saucer-pdf-itext5
9.0.3
2、编写生成pdf的语句(遗漏了一个内容的实体类,在最后面加上)
public static void htmlTopdf(String html, File file) throws Exception {
try {
// step 1
Document document = new Document();
BaseFont bfChinese;
bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
MyFontProvider myFontProvider = new MyFontProvider(BaseColor.BLACK, "", "", false, false, 8, 1, bfChinese);
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
writer.setStrictImageSequence(true);
// step 3
document.open();
// todo 因为html无法生成图片,最后想了一个折中的办法,在pdf里生成,这个是直接通过网络路径转的
String url=ImageBase64("https://img-blog.csdnimg.cn/24828250aeca4b38b7d2d1847ccc4df4.png");
byte [] byteArray = Base64.getDecoder().decode(url);
Image image2 = Image.getInstance(byteArray);
document.add(image2);
float currentWidth = image2.getWidth();
float currentHeight = image2.getHeight();
image2.scalePercent(50);
float newWidth = image2.getWidth();
float newHeight = image2.getHeight();
// todo --------------------也可能写错了,哈哈这段代码是从历史记录里翻出来的。不确定是不是写的有问题,懒得再找。不对的话,可以搜一下。可以肯定能实现图片这个功能
final TagProcessorFactory tagProcessorFactory = Tags.getHtmlTagProcessorFactory();
tagProcessorFactory.removeProcessor(HTML.Tag.IMG);
final CssFilesImpl cssFiles = new CssFilesImpl();
cssFiles.add(XMLWorkerHelper.getInstance().getDefaultCSS());
final StyleAttrCSSResolver cssResolver = new StyleAttrCSSResolver(cssFiles);
final HtmlPipelineContext hpc = new HtmlPipelineContext(new CssAppliersImpl(myFontProvider));
hpc.setAcceptUnknown(true).autoBookmark(true).setTagFactory(tagProcessorFactory);
final HtmlPipeline htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(document, writer));
final Pipeline> pipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
final XMLWorker worker = new XMLWorker(pipeline, true);
final Charset charset = StandardCharsets.UTF_8;
final XMLParser xmlParser = new XMLParser(true, worker, charset);
ByteArrayInputStream bais = new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8));
xmlParser.parse(bais, charset);
// step 5
document.close();
bais.close();
} catch (Exception e) {
throw new Exception(e);
}
}
3、网络图片转地址
rivate static String ImageBase64(String imgUrl) {
URL url = null;
InputStream is = null;
ByteArrayOutputStream outStream = null;
HttpURLConnection httpUrl = null;
try{
url = new URL(imgUrl);
httpUrl = (HttpURLConnection) url.openConnection();
httpUrl.connect();
httpUrl.getInputStream();
is = httpUrl.getInputStream();
outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=is.read(buffer)) != -1 ){
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
// 对字节数组Base64编码
// java11与后面版本用这个
return new Base64Util().encode(outStream.toByteArray());
// java11之前用这个
return new BASE64Encoder().encode(outStream.toByteArray());
}catch (Exception e) {
e.printStackTrace();
}
finally{
if(is != null)
{
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(outStream != null)
{
try {
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(httpUrl != null)
{
httpUrl.disconnect();
}
}
return imgUrl;
}
4、调用传值方法将要生成pdf的图片和内容传给2方法。对html语句要求比较严格,但是如果那个标签的结束符未写,是无法生成的。
public static void main(String[] args) {
String content =
"\n" +
"\n" +
" \n" +
" \n" +
" ddsa \n" +
" \n" +
"\n" +
"\n" +
"123123123\n" +
"";
String url="d:/ss.pdf";
File file = new File(url);
try {
htmlTopdf(content, file);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
最终样式:(图片太大我给注释了)
5、MyFontProvider的实体类
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontProvider;
import com.itextpdf.text.pdf.BaseFont;
public class MyFontProvider implements FontProvider {
private BaseColor bc;
private String fontname;
private String encoding;
private boolean embedded;
private boolean cached;
private float size;
private int style;
private BaseFont baseFont;
public MyFontProvider() {
}
public BaseColor getBc() {
return bc;
}
public void setBc(BaseColor bc) {
this.bc = bc;
}
public String getFontname() {
return fontname;
}
public void setFontname(String fontname) {
this.fontname = fontname;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public boolean isEmbedded() {
return embedded;
}
public void setEmbedded(boolean embedded) {
this.embedded = embedded;
}
public boolean isCached() {
return cached;
}
public void setCached(boolean cached) {
this.cached = cached;
}
public float getSize() {
return size;
}
public void setSize(float size) {
this.size = size;
}
public int getStyle() {
return style;
}
public void setStyle(int style) {
this.style = style;
}
public BaseFont getBaseFont() {
return baseFont;
}
public void setBaseFont(BaseFont baseFont) {
this.baseFont = baseFont;
}
public MyFontProvider(BaseColor bc, String fontname, String encoding, boolean embedded, boolean cached, float size,
int style, BaseFont baseFont) {
super();
this.bc = bc;
this.fontname = fontname;
this.encoding = encoding;
this.embedded = embedded;
this.cached = cached;
this.size = size;
this.style = style;
this.baseFont = baseFont;
}
public Font getFont(String arg0, String arg1, boolean arg2, float arg3, int arg4, BaseColor arg5) {
Font font = null;
if (baseFont == null) {
font = new Font();
} else {
font = new Font(baseFont);
}
font.setColor(arg5);
font.setFamily(fontname);
font.setSize(size);
font.setStyle(arg4);
return font;
}
public boolean isRegistered(String arg0) {
// TODO Auto-generated method stub
return true;
}
}