如何动态生成pdf文件?
pdfService系统
一、 背景
在许多开发需求中都有动态生成pdf文件的需求,例如根据已有的json字符串渲染到一个表格中,然后生成对应的PDF文档,以往的解决方法是调用许多个接口生产pdf文件,其过程复杂和开发时间过长,不利于实际开发的情况。在此情况下需要一个系统来加快完成生成pdf文件的过程,因此pdfService应运而生。
二、PdfService介绍
(一)结构介绍
pdfService是一个SpringBoot项目主要是由service,template和pdfGroovy构成。
(二)功能介绍:
1、IText:iText官网链接
iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件
2、groovy:groovy官网链接
3、pdfService:
其核心运用groovy描绘基本的html,调用iText的java类库生成PDF文档。
pdfService的功能流程是先读取json数据渲染到groovy的html上,然后进入service层调用iText的java类库解析html文件生成PDF文档,最后返回pdf文档的byte文件,其流程图如下:
(三)例子:
现在需要在pdfService里面写一个proform.pdf文档功能,内容要求如下:
1、要有表头,表尾,每页的头部和尾部要有页码的信息。
2、能动态渲染数据,能够插入图片显示。
首先创建四个文件 proforma.json,proforma.groovy,ProformaPdfTemplate.java,PdfGenerator.java
3.1、proforma.json的功能说明:主要是需要渲染的json数据,内容如下:
//以下为渲染到proform.pdf的json数据data
{"data":{"proformaInvoicNo":"3201900351","name1":"MARIA CHIARA ROSSETTO","name2":"NAYA ALDIAS","shipper":"BULGARI IRELAND LTD","consignee":"Bulgari Canada Inc","address1":"Macken House Mayor Upper Dublin1-Ireland DUBLIN DUBLIN 1 +3538750533","address2":"3401 Dufferin Street Unit 163A Toronto, Ontari M6A2T TRONTO M6A2T9 0014167893261","vatNumber1":"IE96787331","vatNumber2":"IE96787331","phone1":"07918316800","phone2":"955288","pickupPalace":"ORIGIN UE","forwarder":"Omlog","deliverTo":"BULGARI STORE VANCOUVER(8959) 737 DUNSMUIR ST. VANCOUVER V7Y1E4 00160046813121","referent":"MARIA CHIARA ROSSETTO","campaign":"HL TRAYS 2019","country":"CANADA","productArryJson":[{"quantity":"2.00","description":"HIGHLIGHT TRAY HS CODE 94038900","poNumber":"1610131298","unitValue":"50.00","totalValue":"100.00"},{"quantity":"1.00","description":"SLG TRAY HS CODE 94038900","poNumber":"1610131298","unitValue":"310.00","totalValue":"310.00"},{"quantity":"3.00","description":"EST - Outside Fabric: 75%WO 25%PA - FOD - Lining: 67%AC 33%PL","poNumber":"1610131298","unitValue":"200.00","totalValue":"600.00"},{"quantity":"4.00","description":"EST - Outside Fabric: 75%WO 25%PA - FOD - Lining: 67%AC 33%PL","poNumber":"1610131298","unitValue":"100.00","totalValue":"400.00"}],"totalValueAmount":"41410.00","tos":"CHECKED","note":"passed","drp":"100%cartoon","extPckg":"BOX","totPcs":"1.000","totCbm":"0.027","totGrossWeight":"6.000","trackingNumber":"1Z0X7W490496235930","dims":"30.0000×30.000×30.000(LxWxH)","grossWeight":"6.000","placeAndDate":"DUBLIN,11/07/2019"}
}
3.2 proforma.groovy功能说明:
groovy内的html内容用html=““” htmlContent “”“来包含,html的内容是由style,body和body内的table组成如图所示内容如下:
其中groovy内的html内容用html=
""" htmlContent"""来包含,html的内容是由style,body和body内的table组成,传入的json数据直接渲染至html用${para.XXX}
,html的表头在table内用< thead> </ thead>
,
表尾用 <tfoot> </foot
>包含,并且在table标签的style属性加上repeat-header:yes;repeat-footer:yes;
后面的iText解析html时会根据此样式生成PDF文档时每页显示表头和表尾的信息。
import net.sf.json.JSONObject
productArryJson=para.productArryJsonproductStr=""""""
//根据productArryJson的大小和内容对象,动态循环显示每一行的数据。
if(productArryJson.size()>0) { for (int i = 0; i < productArryJson.size(); i++) { JSONObject product = (JSONObject) productArryJson.get(i);productStr=productStr+"""<tr> <td colspan="1" class="common_5" style="font-size:12px;">"""+product.getString("quantity")+"""</td><td colspan="6" class="common_5" style="font-size:12px;">"""+product.getString("description")+"""</td><td colspan="1" class="common_5" style="font-size:12px;">"""+product.getString("poNumber")+"""</td><td colspan="1" class="common_5" style="font-size:12px;">€"""+product.getString("unitValue")+"""</td><td colspan="1" class="common_5" style="font-size:12px;">€"""+product.getString("totalValue")+"""</td></tr><tr><td colspan="10" class="common_2" style="height:10px">1.1</td></tr>"""}
}html = """<!--html的样式style设计 -->
<style type="text/css">.common_1{border:1px solid black;color:white;height:20px; font-size:13px;text-align:center;background:black;font-weight:bold;}.common_2{text-align:center;color:white; }.common_3{border:1px solid black;color:black;height:20px; text-align:center;background:white;} .common_4{border:1px solid black;color:white;text-align:center;background:black;height:20px;font-size:15px;font-weight:bold;} .common_5{border:1px solid white;color:black;text-align:center;background:white;height:20px;font-size:15px;}.common_6{text-align:center;color:#999999;}
</style>
<body> <!-- 设计pdf表头,表尾时,需要表的style声明repeat-header:yes;repeat-footer:yes;多张显示会自动循环表头表位内容 --> <table cellspacing="0" valign="center" style="repeat-header:yes;repeat-footer:yes;font-size:10px;width:700px;border:1px solid white"><!--用 <thead></thread>声明表头内容--> <thead> <tr><!--imgPath传入的参数为本地的绝对路径比如C:/img/logo.jpg --> <th colspan="10" ><img src="${para.imgPath}" style="width:700px;height:60px" /></th></tr><tr> <th colspan="10" style="height:15px"></th></tr></thead><tbody><tr><td colspan="5" class="common_1" style="height:30px;font-size:20px;text-align:right;" >Proforma Invoice N°</td><td colspan="5" class="common_1" style="height:30px;font-size:20px;text-align:center;" >${para.proformaInvoicNo}</td></tr><tr><td class="common_2">1.1</td><td class="common_2">1.2</td><td class="common_2">1.3</td><td class="common_2">1.4</td><td class="common_2">1.5</td><td class="common_2">1.6</td><td class="common_2">1.7</td><td class="common_2">1.8</td><td class="common_2">1.9</td><td class="common_2">1.10</td></tr><tr><td class="common_1" colspan="2" style="background:#222222;"><strong>Name</strong></td><td class="common_3" colspan="3" >${para.name1}</td><td class="common_1" colspan="2" style="background:#222222;">Name</td><td class="common_3" colspan="3">${para.name2}</td></tr><tr><td class="common_1" colspan="2" style="background:#222222;">Shipper</td><td class="common_3" colspan="3">${para.shipper}</td><td class="common_1" colspan="2" style="background:#222222;">Consignee</td><td class="common_3" colspan="3">${para.consignee}</td></tr><tr><td colspan="2" class="common_1" rowspan="2" style="height:40px;background:#222222;" >Address</td><td class="common_3" colspan="3" rowspan="2">${para.address1}</td><td colspan="2" class="common_1" rowspan="2" style="height:40px;background:#222222;">Address</td><td class="common_3" colspan="3" rowspan="2">${para.address2}</td></tr><tr></tr><tr><td class="common_1" colspan="2" style="background:#222222;">Var Number</td><td class="common_3" colspan="3">${para.vatNumber1}</td><td class="common_1" colspan="2" style="background:#222222;">Var Number</td><td class="common_3" colspan="3">${para.vatNumber2}</td></tr><tr><td class="common_1" colspan="2" style="background:#222222;">Phone</td><td class="common_3" colspan="3">${para.phone1}</td><td class="common_1" colspan="2" style="background:#222222;">Phone</td><td class="common_3" colspan="3">${para.phone2}</td></tr><tr><td class="common_1" colspan="2" style="background:#222222;">Pick-up Place</td><td class="common_3" colspan="3">${para.pickupPalace}</td><td class="common_1" colspan="2" style="background:#222222;">Forwarder</td><td class="common_3" colspan="3">${para.forwarder}</td></tr><tr><td class="common_2">1.1</td><td class="common_2">1.2</td><td class="common_2">1.3</td><td class="common_2">1.4</td><td class="common_2">1.5</td><td class="common_2">1.6</td><td class="common_2">1.7</td><td class="common_2">1.8</td><td class="common_2">1.9</td><td class="common_2">1.10</td></tr><tr><td colspan="4"></td><td colspan="6">Deliver To : ${para.deliverTo}</td></tr><tr><td colspan="10" class="common_2" style="height:20px">1.1</td></tr><tr><td colspan="4" class="common_4" >Referent:</td><td colspan="3" class="common_4" >Campaign:</td><td colspan="3" class="common_4" >Country:</td></tr><tr><td colspan="4" class="common_4" style="font-weight:normal;" >${para.referent}</td><td colspan="3" class="common_4" style="font-weight:normal;" >${para.campaign}</td><td colspan="3" class="common_4" style="font-weight:normal;">${para.country}</td></tr><tr><td colspan="10" class="common_2" style="height:20px">1.1</td></tr><tr> <td colspan="1" class="common_4" style="border:1px solid white;font-size:12px;">Quantity</td><td colspan="6" class="common_4" style="border:1px solid white;font-size:12px;">Descripion</td><td colspan="1" class="common_4" style="border:1px solid white;font-size:12px;">PO Number</td><td colspan="1" class="common_4" style="border:1px solid white;font-size:12px;">Unit Value</td><td colspan="1" class="common_4" style="border:1px solid white;font-size:12px;">Total Value</td></tr><tr><td class="common_2" colspan="10" style="height:2px;"></td></tr><tr><td class="common_2" colspan="10" style="height:20px;background-color:#7F7F7F;" >Dos stores()</td></tr><tr><td class="common_2" colspan="10" style="height:2px;"></td></tr>"""+productStr+""" <tr> <td colspan="8" class="common_4" style="border:1px solid white;font-weight:normal;">Value for custom purpose only</td><td colspan="1" class="common_4" style="border:1px solid white;font-size:12px;">Total Value</td><td colspan="1" class="common_4" style="border:1px solid white;font-size:12px;">€${para.totalValueAmount}</td></tr><tr><td colspan="10" class="common_2" style="height:20px">1.1</td></tr><tr><td colspan="5" class="common_4" >Tos: ${para.tos}</td><td colspan="5" class="common_4" >Note: ${para.note}</td></tr><tr><td colspan="5" class="common_4" style="font-weight:normal;">DAP: ${para.drp}</td><td colspan="5" class="common_4" ></td></tr><tr><td colspan="10" class="common_2" style="height:20px">1.1</td></tr><tr><td colspan="10" style="font-size:12px">The exporter of the products convered by this document declares that,except where otherwise clearly indicted these products are of Italian<br></br>preferential origin.<br></br>Besides, the exporter declared that all information in this invoice is true and correct.<br></br>La merce non è vincolata a licenze di esportazione e quindi:<br></br>- Regolamento UE n. 101/2012, relativo alla protezione di specie della flora e fauna selvatiche mediante controllo del loro commercio<br></br>(CONVENZIONE DI WASHINGTON - CITES) (codice Y900);<br></br>- Non rientra nell'elenco di beni come da Regolamento CEE n. 1 16/2009 relativo all'esportazione dei beni culturali (codice Y903-Y905);<br></br>- Non rientra nel campo di applicazione del REG( UE ) nr 1332/2013 (g.u. UE L.335 )( codice Y935)<br></br>- Non rientra nell'elenco dei beni come da Regolamento (UE) n.388/2012 del Parlamento Europeo e del Consiglio, del 19 aprile 2012, che <br></br>modifica Regolamento (UE) n.428/2009 del Consiglio, del 5 maggio 2009, che istituisce un regime comunitario di controllo delle<br></br>exortazioni,del trasferimento.dell'intermediazione e del transito di prodotti a duplice uso (Dual Use)(Y901)<br></br></td></tr><tr><td colspan="10" class="common_2" style="height:40px">1.1</td></tr><tr><td colspan="2" class="common_4" >EXT:PCKG</td><td colspan="2" class="common_4" >TOT PCS</td><td colspan="2" class="common_4" >TOT CBM</td><td colspan="4" class="common_4" >TOT GROSS WEIGHT</td></tr><tr><td colspan="2" class="common_4" style="font-weight:normal;">${para.extPckg}</td><td colspan="2" class="common_4" style="font-weight:normal;">${para.totPcs}</td><td colspan="2" class="common_4" style="font-weight:normal;">${para.totCbm}</td><td colspan="4" class="common_4" style="font-weight:normal;">${para.totGrossWeight}</td></tr><tr><td colspan="10" class="common_2" style="height:20px">1.1</td></tr><tr><td colspan="3" class="common_4">TRACKING NUMBER</td><td colspan="4" class="common_4">DIMS(cm)</td><td colspan="3" class="common_4">GROS WEIGHT</td></tr><tr><td colspan="3" class="common_4" style="font-weight:normal;">${para.trackingNumber}</td><td colspan="4" class="common_4" style="font-weight:normal;">${para.dims}</td><td colspan="3" class="common_4" style="font-weight:normal;">${para.grossWeight}</td></tr><tr><td colspan="10" class="common_2" style="height:750px;">1.1</td></tr><tr><td colspan="10" style="text-align:left;font-size:15px">${para.placeAndDate}</td></tr><tr><td colspan="10" style="text-align:right;font-size:15px">Signature </td></tr><tr> <td colspan="10" class="common_2" style="height:10px">1.1</td></tr><tr><td colspan="10" style="text-align:right;">${para.proformaInvoicNo}</td></tr></tbody><!--表位内容用 <tfoot></tfoot>包含--> <tfoot><tr><td colspan="10" class="common_2" style="height:40px;"></td></tr><tr><td colspan="10" class="common_6"><strong>BULGARIIRELAND</strong> Limited- Incorporated in lreland under Compan Reg. No 454082</td></tr><tr><td colspan="10" class="common_2" style="height:5px">1.1</td></tr> <tr><td colspan="10" class="common_6">Business/CorrespondenceAddress-MackenHouse,Castleforbes Square,Upper Mayor Street Dublin 1</td> </tr><tr><td colspan="10" class="common_2" style="height:5px">1.1</td></tr> <tr><td colspan="10" class="common_6">Registered Office- 70 Sir John Rogerson's Quay,Dublin 2</td></tr><tr><td colspan="10" class="common_2" style="height:5px">1.1</td></tr> <tr><td colspan="10" class="common_6">VAT Reg. No: IE 96787331</td> </tr></tfoot></table>
</body>
"""
3.3 ProformaPdfTemplate.java功能说明
继承了Itext的PdfPageEventHelper,主要可以初始化字体样式,设置页码的显示等。内容如下:
package com.om3000.v2.standalone.ws.pdfService.template;import java.io.IOException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;public class ProformaPdfTemplate extends PdfPageEventHelper {//页面总数 totalPageTplprivate PdfTemplate totalPageTpl;//字体样式private BaseFont bf = null;//页脚private Font fontDetail = null;//页头private Font fontHeader = null;//字体大小private int footFontSize = 8;//开启html文档读取并且写入pdfpublic void onOpenDocument(PdfWriter writer, Document document) {totalPageTpl = writer.getDirectContent().createTemplate(50, 50);}public void onEndPage(PdfWriter writer, Document document) {this.initFont();this.addPageInfo(writer, document);}//初始化字体样式private void initFont() {try {if (bf == null) {bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);}if (fontHeader == null) {BaseColor bwlBLUE = new BaseColor(104, 130, 194);fontHeader = new Font(bf, 14, Font.BOLD, bwlBLUE);}if (fontDetail == null) {fontDetail = new Font(bf, footFontSize, Font.NORMAL);}} catch (DocumentException | IOException e) {e.printStackTrace();}}//页头和页尾增加页码信息private void addPageInfo(PdfWriter writer, Document document) {int pageS = writer.getPageNumber();String foot1 = pageS + " page" + " /";Phrase footer = new Phrase(foot1, fontDetail);PdfContentByte cb = writer.getDirectContent();//页脚的页码信息位置设置ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, footer, document.right() - 300, document.bottom() - 30, 0);cb.addTemplate(totalPageTpl, document.right() - 285, document.bottom() - 30);String head1 = "Page " + pageS + " of";Phrase header = new Phrase(head1, fontDetail);//页头的页码信息位置设置ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, header, document.right() - 40, document.bottom() + 750, 0);cb.addTemplate(totalPageTpl, document.right() - 25, document.bottom() + 750);}//关闭html文档public void onCloseDocument(PdfWriter writer, Document document) {totalPageTpl.beginText();totalPageTpl.setFontAndSize(bf, footFontSize);//设置页码的总页数String foot2 = " " + (writer.getPageNumber() - 1);totalPageTpl.showText(foot2);totalPageTpl.endText();totalPageTpl.closePath();}
}
3.4 PdfGenerator.java功能说明
一个生成pdf文档公共调用的类,传入groovy的html,需要渲染的数据data和设置的模板template,内容如下
package com.om3000.v2.standalone.ws.pdfService.generator;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Map;
import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.RectangleReadOnly;
import com.itextpdf.text.pdf.PdfPageEvent;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.TagProcessorFactory;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import com.om3000.v2.standalone.ws.common.util.Utils;public class PdfGenerator {//需要渲染的json数据dataprivate Map<String, Object> data;//pdf的模板private PdfPageEvent template;//最后生成的pdf二进制输出流private ByteArrayOutputStream outputOs = new ByteArrayOutputStream();//读取groovy文件的html内容private String gvContent;private byte[] result = null;public PdfGenerator(String gvContent, Map<String, Object> data, PdfPageEvent template) {this.gvContent = gvContent;this.data = data;this.template = template;}public boolean gen() {//将 groovy的html内容和json数据data动态渲染结合成htmlString html = Utils.compileGroovyToHtml(gvContent, data);outputOs = new ByteArrayOutputStream();try {createPdf(outputOs, html, template);} catch (Exception e) {e.printStackTrace();}result = outputOs.toByteArray();if (result.length > 0) {return true;} else {return false;}}//根据htmlStr内容和模板template内容,生成pdf文件文档的OutputStreampublic void createPdf(OutputStream os, String htmlStr, PdfPageEvent template) throws Exception {Rectangle pageSize = new RectangleReadOnly(625, 842);Document document = new Document(pageSize, 50, 30, 30, 70);PdfWriter writer = PdfWriter.getInstance(document, os);writer.setPageEvent(template);document.open();CSSResolver cssResolver = new StyleAttrCSSResolver();// HTMLXMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider() {@Overridepublic Font getFont(String fontName, String encoding, float size, int style) {return super.getFont(fontName, encoding, size, style);}};CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);TagProcessorFactory factory = Tags.getHtmlTagProcessorFactory();htmlContext.setTagFactory(factory);// PipelinesPdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);// XML WorkerdfesdsdadsdasdadasdaXMLWorker worker = new XMLWorker(css, true);XMLParser p = new XMLParser(worker);p.parse(new ByteArrayInputStream(htmlStr.getBytes()), Charset.forName("UTF-8"));// step 5document.close();}public byte[] toByteResult() {if (result != null) {return result;}return null;}public String toBase64Result() {if (result != null) {return Utils.toBase64String(result);}return null;}
}
最后只需要一个测试类,即可生成你想要的pdf文件:
package com.om3000.v2.standalone.ws.pdfService.service;import static org.junit.Assert.assertEquals;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;import org.apache.commons.io.FileUtils;
import org.junit.Test;import com.itextpdf.text.pdf.PdfPageEvent;
import com.om3000.v2.standalone.ws.pdfService.generator.PdfGenerator;
import com.om3000.v2.standalone.ws.pdfService.template.ProformaPdfTemplate;import net.sf.json.JSONObject;public class pdfGenTest {//groovy文件位置private static final String proformaGroovyPath = "src/main/resources/pdfGroovy/proforma.groovy";//pdfJson数据data文件位置private static final String proformaJsonPath = "src/test/resources/pdfJson/proforma.json";//需要引入的图片位置private static final String imagLogoPath = "src/main/resources/img/logo.jpg";@SuppressWarnings("unchecked")@Testpublic void genProformaPdf() throws IOException {//1、读取json文件内容引入pdf模板、相关参数设置公共类PdfGeneratorFile file = new File(proformaJsonPath);String str = FileUtils.readFileToString(file);JSONObject jsonObject = JSONObject.fromObject(str);//2、设置json的data数据JSONObject data = (JSONObject) jsonObject.get("data");data.put("imgPath", imagLogoPath);//3、读取groovy文件内容,并且动态渲染数据String gvContent = FileUtils.readFileToString(new File(proformaGroovyPath));//4、引用pdf的模板PdfPageEvent template = new ProformaPdfTemplate();//5、进入生成pdf的公共类PdfGenerator ,传入groovy内容,json数据data,pdf模板,三个参数PdfGenerator g = new PdfGenerator(gvContent, data, template);assertEquals(true, g.gen());//6、将生成的pdf获取其内容的二进制,并写入生成到本地c:\\pdf\\proforma.pdfbyte[] bb = g.toByteResult();FileOutputStream os = new FileOutputStream(new File("c:\\pdf\\proforma.pdf"));os.write(bb);os.close();}
}
第一次写,如有不足多多谅解,欢迎留言!
如何动态生成pdf文件?相关推荐
- java在linux生成pdf文件,从 Java 应用程序动态生成 PDF 文件
简介: 如果您的应用程序需要动态生成 PDF 文档,那么您需要 iText 库.开源的 iText 库使得 PDF 的创建变得轻松易行.本文介绍了 iText 并提供了一个使用它从 Java 技术应用 ...
- java动态生成pdf文件的方法
java动态生成pdf文件 文章目录 java动态生成pdf文件 前言 一.生成pdf模板 二.使用步骤 1.使用jar包 2.pdf实现方法 总结 前言 java开发过程中难免会遇到生成文件的需求, ...
- Java读取pdf模板,并动态生成pdf文件,如动态生成准考证
Java读取pdf模板,并动态生成pdf文件,如动态生成准考证 前几天遇到了一个生成准考证的需求,并提供用户下载,然后百度了一圈还是觉得使用itextpdf这个框架好用点.但是还需要找到一个能创建 ...
- java使用world模板动态生成PDF文件
根据项目需求,需要用到一个功能,根据页面参数需要动态的生成一个world,并将world生成两份PDF文件,一份正式文件,一份临时的电子文件(带有二维码,扫描可以下载正式文件的电子版本).同时上传到文 ...
- java设置pdf不可编辑_Java动态生成pdf文件(使用itext编辑pdf)
一.创建pdf模板 使用PDFelement制作pdf模板(数据域的名称对应后面插入的key) 二.导入maven依赖 com.itextpdf itextpdf 5.5.13 com.itextpd ...
- Java动态生成pdf文件(用于实时生成电子证书)
1.首先,新建一个word文档,内容如下,另存为pdf格式,我的命名:mytest.pdf. 2.用Adobe Acrobat Pro 打开刚刚制作的pdf文件.如下图: 3.点击创建–>PDF ...
- java maven 读写pdf_Java动态生成pdf文件(使用itext编辑pdf)
一.创建pdf模板 使用PDFelement制作pdf模板(数据域的名称对应后面插入的key) 二.导入maven依赖 com.itextpdf itextpdf 5.5.13 com.itextpd ...
- .NET动态生成PDF文件(利用iTextSharp)
1.前台页面上: Code<div><asp:TextBox ID="TextBox1"runat="server"></asp: ...
- java动态生成pdf文件(使用itext编辑pdf)
最新文章
- [转载] 30分钟泛型教程
- Nginx中gzip_static使用测试
- linux多线程学习设置线程调度权限
- 2013_chengdu_visit
- Magento 获取系统设置 How to get data from Magento System Configuration
- 360 支持linux版本下载地址,360安全浏览器国产稳定版本发布,提供deb软件包下载,附介绍...
- torch中loss.bacword的理解
- STM32——库函数版——数码管动态显示程序
- 成为一名Java高级工程师需要掌握哪些技能
- VS2010SP1中文版安装问题
- Linux系统Ubuntu vim安装plugin
- 微信模拟地理位置_微信伪装地理位置是什么个原理
- wps2016热点永久关闭
- js根据身份证获取年龄
- python爬虫构建国外代理池_建立爬虫代理ip池
- STM32涉及到的汇编基础知识
- 安全帽图像识别python_基于opencv的安全帽佩戴检测
- 各大互联网大厂年终奖一览表,又是别人家的公司!
- CSS3线性渐变与径向渐变
- Redis使用setnx实现分布式锁及其问题、优化
热门文章
- 广东职称英语计算机考试时间安排,2017年广东省职称计算机考试报名时间
- 双色球机选彩票shell脚本
- Win系统下打开串口转换USB口的RS232串口,打不开问题
- corex9服务器组装攻略,服务器级的X9机箱 只因“发烧”而生_Tt Core X9_机箱电源评测-中关村在线...
- 正反转可控的步进电机
- 低秩矩阵(Low-Rank)的意义
- dell服务器uefi启动不了系统安装系统安装,戴尔做uefi系统-uefi启动进不去系统怎么办呀...
- 周日:潭杯山-潭柘寺拉练
- 将WORD中的文档编号转换成文字(宏命令法)
- 腾讯应用宝整改通知 隐私政策