itext实现PDF生成的两种方式-从HTML到PDF
maven依赖pom配置:
<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.10</version> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.10</version> </dependency>
(一)第一种生成
private void doGenerateContractPdf(String contractUrl, String serverRealPath, String pdfFileName) throws Exception { com.itextpdf.text.Document document = new com.itextpdf.text.Document(PageSize.LETTER); try { PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(serverRealPath + pdfFileName)); document.open(); String responseString = HttpUtils.httpPostUrlForPdf(contractUrl); XMLWorkerHelper worker = XMLWorkerHelper.getInstance(); worker.parseXHtml(pdfWriter, document, new ByteArrayInputStream(responseString.getBytes()), Charset.forName("UTF-8"), new AsianFontProvider()); } catch (Exception e) { logger.error("==========异常==========",e); throw e; } finally { document.close(); } }
(二)第二种生成 自定义Image类支持BASE64图片生成
private void doGenerateContractPdfForBase64(String contractUrl, String serverRealPath, String pdfFileName) throws Exception {
com.itextpdf.text.Document document = new com.itextpdf.text.Document(PageSize.LETTER); try { PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(serverRealPath + pdfFileName)); document.open(); String responseString = HttpUtils.httpPostUrlForPdf(contractUrl); InputStream in = new ByteArrayInputStream(responseString.getBytes()); com.itextpdf.tool.xml.html.TagProcessorFactory tagProcessorFactory = Tags.getHtmlTagProcessorFactory(); tagProcessorFactory.removeProcessor(HTML.Tag.IMG); tagProcessorFactory.addProcessor(new ImageTagProcessor(), HTML.Tag.IMG); CssFilesImpl cssFiles = new CssFilesImpl(); cssFiles.add(XMLWorkerHelper.getInstance().getDefaultCSS()); StyleAttrCSSResolver cssResolver = new StyleAttrCSSResolver(cssFiles); HtmlPipelineContext hpc = new HtmlPipelineContext(new CssAppliersImpl(new AsianFontProvider())); hpc.setAcceptUnknown(true).autoBookmark(true).setTagFactory(tagProcessorFactory); HtmlPipeline htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(document, pdfWriter)); CssResolverPipeline pipeline = new CssResolverPipeline(cssResolver, htmlPipeline); XMLWorker worker = new XMLWorker(pipeline, true); Charset charset = Charset.forName("UTF-8"); XMLParser parser = new XMLParser(true, worker, Charset.forName("UTF-8")); if(charset != null) { parser.parse(in, charset); } else { parser.parse(in); } } catch (Exception e) { logger.error("==========异常==========",e); throw e; } finally { document.close(); } }
import java.util.ArrayList; import java.util.List; import java.util.Map; import com.itextpdf.text.Chunk; import com.itextpdf.text.Element; import com.itextpdf.text.Image; import com.itextpdf.text.pdf.codec.Base64; import com.itextpdf.tool.xml.NoCustomContextException; import com.itextpdf.tool.xml.Tag; import com.itextpdf.tool.xml.WorkerContext; import com.itextpdf.tool.xml.exceptions.RuntimeWorkerException; import com.itextpdf.tool.xml.html.HTML; import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext; /** * Created by gaozz on 2017/1/17. */ public class ImageTagProcessor extends com.itextpdf.tool.xml.html.Image { /* * (non-Javadoc) * * @see com.itextpdf.tool.xml.TagProcessor#endElement(com.itextpdf.tool.xml.Tag, java.util.List, com.itextpdf.text.Document) */ @Override public List<Element> end(final WorkerContext ctx, final Tag tag, final List<Element> currentContent) { final Map<String, String> attributes = tag.getAttributes(); String src = attributes.get(HTML.Attribute.SRC); List<Element> elements = new ArrayList<Element>(1); if (null != src && src.length() > 0) { Image img = null; if (src.startsWith("data:image/")) { final String base64Data = src.substring(src.indexOf(",") + 1); try { img = Image.getInstance(Base64.decode(base64Data)); } catch (Exception e) { throw new RuntimeException(e); } if (img != null) { try { final HtmlPipelineContext htmlPipelineContext = getHtmlPipelineContext(ctx); elements.add(getCssAppliers().apply(new Chunk((com.itextpdf.text.Image) getCssAppliers().apply(img, tag, htmlPipelineContext), 0, 0, true), tag, htmlPipelineContext)); } catch (NoCustomContextException e) { throw new RuntimeWorkerException(e); } } } if (img == null) { elements = super.end(ctx, tag, currentContent); } } return elements; } } 字体类:
importcom.itextpdf.text.BaseColor; import com.itextpdf.text.Font; import com.itextpdf.text.FontFactory; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.tool.xml.XMLWorkerFontProvider; import com.thinkgem.jeesite.common.config.Global; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class AsianFontProvider extends XMLWorkerFontProvider { protected Logger logger = LoggerFactory.getLogger(AsianFontProvider.class); private static final String contractPdfFontLocation = Global.getConfig("contractPdfFontLocation"); public Font getFont(final String fontname, final String encoding, final boolean embedded, final float size, final int style, final BaseColor color) { try { FontFactory.register(contractPdfFontLocation + "/simhei.ttf"); Font font3 = FontFactory.getFont("simhei", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 12,style); return font3; } catch (Exception e) { logger.error("==========获取字体出现异常==========",e); } return null; } }
配置文件:contractPdfFontLocation=D:\\pdffonts PS:
<!-- httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> <exclusions> <exclusion> <artifactId>commons-logging</artifactId> <groupId>commons-logging</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.4</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.2</version> </dependency>
public static String httpPostUrlForPdf(String url) { // 设置HTTP请求参数 String result = null; CloseableHttpClient client = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(url); try { CloseableHttpResponse response = client.execute(httpGet); result = EntityUtils.toString(response.getEntity(), "UTF-8"); } catch (ClientProtocolException e) { logger.error("http接口调用异常:url is::" + url, e); return null; } catch (IOException e) { logger.error("http接口调用异常:url is::" + url, e); return null; } finally { try { client.close(); } catch (IOException e) { logger.error("http接口调用异常:url is::" + url, e); } } return result; }