富文本生成pdf
首先引入相关jar包
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
<!-- 支持中文 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!-- 支持css样式渲染 -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.16</version>
</dependency>
要保证富文本数据是完成html格式,不然很多数据样式会有问题,我的保存没有,统一添加的,前缀加了
String replace1 ="<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \".dtd \">\n" +"<html xmlns=\" \">\n" +" <head>\n" +" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" +" <meta name=\"Generator\" content=\"EditPlus®\"/>\n" +" <meta name=\"Author\" content=\"\"/>\n" +" <meta name=\"Keywords\" content=\"\"/>\n" +" <meta name=\"Description\" content=\"\"/>\n" +" <title>Document</title>\n" +"\n" +"\n" +"<style type=\"text/css\">\n" +"body {\n" +" p{line-height:30px}\n" +"}\n" +"::v-deep h5, .h5 {\n" +" font-size: 14px;\n" +"}\n" +"\n" +"::v-deep h4, .h4 {\n" +" font-size: 16px;\n" +" font-weight: bold;\n" +"}\n" +"\n" +"::v-deep h3, .h3 {\n" +" font-size: 18px;\n" +" font-weight: bold;\n" +"}\n" +"\n" +"::v-deep h2, .h2 {\n" +" font-size: 20px;\n" +" font-weight: bold;\n" +"}\n" +"\n" +"::v-deep h1, .h1 {\n" +" font-size: 22px;\n" +" font-weight: bold;\n" +"}\n" +"::v-deep i {\n" +" font-style: italic\n" +"}\n" +"::v-deep .w-e-toolbar .w-e-menu i {\n" +" font-style: normal;\n" +"}\n" +"::v-deep ol {\n" +" list-style-type: decimal;\n" +"}\n" +"font[size=\"1\"] {\n" +" font-size: 12px;\n" +"}\n" +"font[size=\"2\"] {\n" +" font-size: 14px;\n" +"}\n" +"font[size=\"3\"] {\n" +" font-size: 16px;\n" +"}\n" +"font[size=\"4\"] {\n" +" font-size: 18px;\n" +"}\n" +"font[size=\"5\"] {\n" +" font-size: 24px;\n" +"}\n" +"font[size=\"6\"] {\n" +" font-size: 32px;\n" +"}\n" +"font[size=\"7\"] {\n" +" font-size: 48px;\n" +"}\n" +"/* blockquote 样式 */\n" +"::v-deep blockquote {\n" +" display: block;\n" +" border-left: 8px solid #d0e5f2;\n" +" padding: 5px 10px;\n" +" margin: 10px 0;\n" +" line-height: 1.4;\n" +" min-height: 24px;\n" +" font-size: 100%;\n" +" background-color: #f1f1f1;\n" +"}\n" +"/* table 样式 */\n" +"/* table 样式 */\n" +"::v-deep table {\n" +" border-top: 1px solid #ccc;\n" +" border-left: 1px solid #ccc;\n" +"}\n" +"::v-deep table td,\n" +"::v-deep table th {\n" +" border-bottom: 1px solid #ccc;\n" +" border-right: 1px solid #ccc;\n" +" padding: 3px 5px;\n" +" height:32px;\n" +"}\n" +"::v-deep table th {\n" +" border-bottom: 2px solid #ccc;\n" +" text-align: center;\n" +" background-color: #f1f1f1 ;\n" +"}\n" +"</style>\n" +" </head>\n" +" <body style=\"line-height: 30px\">";content.replace("<html>",replace1);content.replace("</html>","</body></html>");
接下来是相关的工具
主要工具代码
UploadFileDTO 我们自己封装的文件返回类,自己换自己的
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.codec.Base64;
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.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.AbstractImageProvider;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.Charset;@Component
@Slf4j
public class ContractPdfUtil {@Resourceprivate FileUtil fileUtil;
//TODO 我们自己封装文件上传工具,自己用自己的@Resourceprivate FileService fileService;// 生成hellowlodpublic void hellowPdf() throws IOException, DocumentException {Document document = new Document(PageSize.A4);//第二步,创建Writer实例PdfWriter.getInstance(document, new FileOutputStream("hello.pdf"));//创建中文字体BaseFont bfchinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);Font fontChinese = new Font(bfchinese, 12, Font.NORMAL);//第三步,打开文档document.open();//第四步,写入内容Paragraph paragraph = new Paragraph("hello world", fontChinese);document.add(paragraph);//第五步,关闭文档document.close();}// ----------------------讲html生成pdf---------------------------------/*** 创建PDF文件* @param htmlStr* @throws Exception*/public UploadFileDTO writeToOutputStreamAsPDF(Integer companyId,String name,String htmlStr) throws Exception {
// String targetFile = "pdfDemo1.pdf";
// File targeFile = new File(targetFile);
// if(targeFile.exists()) {
// targeFile.delete();
// }String filePath = null;String fileName = "合同"+System.currentTimeMillis() + ".pdf";try {filePath = fileUtil.newfilePath(fileName);} catch (Exception e) {e.printStackTrace();}//定义pdf文件尺寸,采用A4横切Document document = new Document(PageSize.A4, 70, 70, 40, 50);// 左、右、上、下间距//定义输出路径PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filePath));PdfReportM1HeaderFooter header = new PdfReportM1HeaderFooter("", 8, PageSize.A4);writer.setPageEvent(header);writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);document.open();// CSSCSSResolver cssResolver = new StyleAttrCSSResolver();CssAppliers cssAppliers = new CssAppliersImpl(new XMLWorkerFontProvider(){@Overridepublic Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color) {try {//用于中文显示的ProviderBaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);log.error("bfChinese == > {}",bfChinese ==null);return new Font(bfChinese, size, style);} catch (Exception e) {log.error("getFont ",e);return super.getFont(fontname, encoding, size, style);}}});//htmlHtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());htmlContext.setImageProvider(new AbstractImageProvider() {@Overridepublic Image retrieve(String src) {//支持图片显示int pos = src.indexOf("base64,");try {if (src.startsWith("data") && pos > 0) {byte[] img = Base64.decode(src.substring(pos + 7));return Image.getInstance(img);} else if (src.startsWith("http")) {return Image.getInstance(src);}} catch (BadElementException ex) {return null;} catch (IOException ex) {return null;}return null;}@Overridepublic String getImageRootPath() {return null;}});// PipelinesPdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);// XML Workerfinal Charset charset = Charset.forName("UTF-8");XMLWorker worker = new XMLWorker(css, true);XMLParser p = new XMLParser(true ,worker,charset);try {p.parse(new ByteArrayInputStream(htmlStr.getBytes("UTF-8")),charset);}catch (Exception e){e.getMessage();}document.close();UploadFileDTO uploadFileDTO = fileService.fileUploadBytes(FileUtils.readFileToByteArray(new File(filePath)), companyId + "/contract/order/" + fileName);
return uploadFileDTO;}/*** 读取 HTML 文件* @return*/private static String readHtmlFile() {StringBuffer textHtml = new StringBuffer();try {File file = new File("D:\\test.html");BufferedReader reader = new BufferedReader(new FileReader(file));String tempString = null;// 一次读入一行,直到读入null为文件结束while ((tempString = reader.readLine()) != null) {textHtml.append(tempString);}reader.close();} catch (IOException e) {System.out.println("e"+e.toString());return null;}return textHtml.toString();}public static void main(String[] args) throws Exception {}
}
接下来是页眉页脚样式啥的支持类
import java.io.IOException;import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
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 PdfReportM1HeaderFooter extends PdfPageEventHelper {/*** 页眉*/public String header = "";/*** 文档字体大小,页脚页眉最好和文本大小一致*/public int presentFontSize = 12;/*** 文档页面大小,最好前面传入,否则默认为A4纸张*/public Rectangle pageSize = PageSize.A4;// 模板public PdfTemplate total;// 基础字体对象public BaseFont bf = null;// 利用基础字体生成的字体对象,一般用于生成中文文字public Font fontDetail = null;/**** Creates a new instance of PdfReportM1HeaderFooter 无参构造方法.**/public PdfReportM1HeaderFooter() {}/**** Creates a new instance of PdfReportM1HeaderFooter 构造方法.** @param yeMei* 页眉字符串* @param presentFontSize* 数据体字体大小* @param pageSize* 页面文档大小,A4,A5,A6横转翻转等Rectangle对象*/public PdfReportM1HeaderFooter(String yeMei, int presentFontSize, Rectangle pageSize) {this.header = yeMei;this.presentFontSize = presentFontSize;this.pageSize = pageSize;}public void setHeader(String header) {this.header = header;}public void setPresentFontSize(int presentFontSize) {this.presentFontSize = presentFontSize;}/**** TODO 文档打开时创建模板** @see PdfPageEventHelper#onOpenDocument(PdfWriter, Document)*/public void onOpenDocument(PdfWriter writer, Document document) {total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高}/**** TODO 关闭每页的时候,写入页眉,写入'第几页共'这几个字。** @see PdfPageEventHelper#onEndPage(PdfWriter, Document)*/public void onEndPage(PdfWriter writer, Document document) {try {if (bf == null) {bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);}if (fontDetail == null) {fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体}} catch (DocumentException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}// 1.写入页眉ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, new Phrase(header, fontDetail), document.left(), document.top() + 20, 0);// 2.写入前半部分的 第 X页/共int pageS = writer.getPageNumber();String foot1 = "第 " + pageS + " 页 /共";Phrase footer = new Phrase(foot1, fontDetail);// 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = lenfloat len = bf.getWidthPoint(foot1, presentFontSize);// 4.拿到当前的PdfContentBytePdfContentByte cb = writer.getDirectContent();//自己增加的/*if(pageS==1){Phrase footerLeft = new Phrase("978-1-4799-0530-031.00 ©2013 IEEE", fontDetail);ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, footerLeft, document.left(), document.bottom() - 20, 0);}
*/// 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F 再给偏移20F适合人类视觉感受,否则肉眼看上去就太偏左了 ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了;注意Y轴是从下往上累加的,最上方的Top值是大于Bottom好几百开外的。ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, footer, (document.rightMargin() + document.right() + document.leftMargin() - document.left() - len) / 2.0F + 20F, document.bottom() - 20, 0);// 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F + len , y 轴和之前的保持一致,底边界-20cb.addTemplate(total, (document.rightMargin() + document.right() + document.leftMargin() - document.left()) / 2.0F + 20F, document.bottom() - 20); // 调节模版显示的位置}/**** TODO 关闭文档时,替换模板,完成整个页眉页脚组件** @see PdfPageEventHelper#onCloseDocument(PdfWriter, Document)*/public void onCloseDocument(PdfWriter writer, Document document) {// 7.最后一步了,就是关闭文档的时候,将模板替换成实际的 Y 值,至此,page x of y 制作完毕,完美兼容各种文档size。total.beginText();total.setFontAndSize(bf, presentFontSize);// 生成的模版的字体、颜色String foot2 = " " + (writer.getPageNumber()) + " 页";total.showText(foot2);// 模版显示的内容total.endText();total.closePath();}
}
4到这就完成了,测试一下
UploadFileDTO uploadFileDTO = new UploadFileDTO() ;
try {
uploadFileDTO = contractPdfUtil.writeToOutputStreamAsPDF(ro.getCompanyId(), templateEmailDTO.getSubject(), templateEmailDTO.getContent());
} catch (Exception exception) {
exception.printStackTrace();
}
富文本生成pdf
首先引入相关jar包
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
<!-- 支持中文 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!-- 支持css样式渲染 -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.16</version>
</dependency>
要保证富文本数据是完成html格式,不然很多数据样式会有问题,我的保存没有,统一添加的,前缀加了
String replace1 ="<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \".dtd \">\n" +"<html xmlns=\" \">\n" +" <head>\n" +" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n" +" <meta name=\"Generator\" content=\"EditPlus®\"/>\n" +" <meta name=\"Author\" content=\"\"/>\n" +" <meta name=\"Keywords\" content=\"\"/>\n" +" <meta name=\"Description\" content=\"\"/>\n" +" <title>Document</title>\n" +"\n" +"\n" +"<style type=\"text/css\">\n" +"body {\n" +" p{line-height:30px}\n" +"}\n" +"::v-deep h5, .h5 {\n" +" font-size: 14px;\n" +"}\n" +"\n" +"::v-deep h4, .h4 {\n" +" font-size: 16px;\n" +" font-weight: bold;\n" +"}\n" +"\n" +"::v-deep h3, .h3 {\n" +" font-size: 18px;\n" +" font-weight: bold;\n" +"}\n" +"\n" +"::v-deep h2, .h2 {\n" +" font-size: 20px;\n" +" font-weight: bold;\n" +"}\n" +"\n" +"::v-deep h1, .h1 {\n" +" font-size: 22px;\n" +" font-weight: bold;\n" +"}\n" +"::v-deep i {\n" +" font-style: italic\n" +"}\n" +"::v-deep .w-e-toolbar .w-e-menu i {\n" +" font-style: normal;\n" +"}\n" +"::v-deep ol {\n" +" list-style-type: decimal;\n" +"}\n" +"font[size=\"1\"] {\n" +" font-size: 12px;\n" +"}\n" +"font[size=\"2\"] {\n" +" font-size: 14px;\n" +"}\n" +"font[size=\"3\"] {\n" +" font-size: 16px;\n" +"}\n" +"font[size=\"4\"] {\n" +" font-size: 18px;\n" +"}\n" +"font[size=\"5\"] {\n" +" font-size: 24px;\n" +"}\n" +"font[size=\"6\"] {\n" +" font-size: 32px;\n" +"}\n" +"font[size=\"7\"] {\n" +" font-size: 48px;\n" +"}\n" +"/* blockquote 样式 */\n" +"::v-deep blockquote {\n" +" display: block;\n" +" border-left: 8px solid #d0e5f2;\n" +" padding: 5px 10px;\n" +" margin: 10px 0;\n" +" line-height: 1.4;\n" +" min-height: 24px;\n" +" font-size: 100%;\n" +" background-color: #f1f1f1;\n" +"}\n" +"/* table 样式 */\n" +"/* table 样式 */\n" +"::v-deep table {\n" +" border-top: 1px solid #ccc;\n" +" border-left: 1px solid #ccc;\n" +"}\n" +"::v-deep table td,\n" +"::v-deep table th {\n" +" border-bottom: 1px solid #ccc;\n" +" border-right: 1px solid #ccc;\n" +" padding: 3px 5px;\n" +" height:32px;\n" +"}\n" +"::v-deep table th {\n" +" border-bottom: 2px solid #ccc;\n" +" text-align: center;\n" +" background-color: #f1f1f1 ;\n" +"}\n" +"</style>\n" +" </head>\n" +" <body style=\"line-height: 30px\">";content.replace("<html>",replace1);content.replace("</html>","</body></html>");
接下来是相关的工具
主要工具代码
UploadFileDTO 我们自己封装的文件返回类,自己换自己的
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.codec.Base64;
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.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.AbstractImageProvider;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.Charset;@Component
@Slf4j
public class ContractPdfUtil {@Resourceprivate FileUtil fileUtil;
//TODO 我们自己封装文件上传工具,自己用自己的@Resourceprivate FileService fileService;// 生成hellowlodpublic void hellowPdf() throws IOException, DocumentException {Document document = new Document(PageSize.A4);//第二步,创建Writer实例PdfWriter.getInstance(document, new FileOutputStream("hello.pdf"));//创建中文字体BaseFont bfchinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);Font fontChinese = new Font(bfchinese, 12, Font.NORMAL);//第三步,打开文档document.open();//第四步,写入内容Paragraph paragraph = new Paragraph("hello world", fontChinese);document.add(paragraph);//第五步,关闭文档document.close();}// ----------------------讲html生成pdf---------------------------------/*** 创建PDF文件* @param htmlStr* @throws Exception*/public UploadFileDTO writeToOutputStreamAsPDF(Integer companyId,String name,String htmlStr) throws Exception {
// String targetFile = "pdfDemo1.pdf";
// File targeFile = new File(targetFile);
// if(targeFile.exists()) {
// targeFile.delete();
// }String filePath = null;String fileName = "合同"+System.currentTimeMillis() + ".pdf";try {filePath = fileUtil.newfilePath(fileName);} catch (Exception e) {e.printStackTrace();}//定义pdf文件尺寸,采用A4横切Document document = new Document(PageSize.A4, 70, 70, 40, 50);// 左、右、上、下间距//定义输出路径PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filePath));PdfReportM1HeaderFooter header = new PdfReportM1HeaderFooter("", 8, PageSize.A4);writer.setPageEvent(header);writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);document.open();// CSSCSSResolver cssResolver = new StyleAttrCSSResolver();CssAppliers cssAppliers = new CssAppliersImpl(new XMLWorkerFontProvider(){@Overridepublic Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color) {try {//用于中文显示的ProviderBaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);log.error("bfChinese == > {}",bfChinese ==null);return new Font(bfChinese, size, style);} catch (Exception e) {log.error("getFont ",e);return super.getFont(fontname, encoding, size, style);}}});//htmlHtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());htmlContext.setImageProvider(new AbstractImageProvider() {@Overridepublic Image retrieve(String src) {//支持图片显示int pos = src.indexOf("base64,");try {if (src.startsWith("data") && pos > 0) {byte[] img = Base64.decode(src.substring(pos + 7));return Image.getInstance(img);} else if (src.startsWith("http")) {return Image.getInstance(src);}} catch (BadElementException ex) {return null;} catch (IOException ex) {return null;}return null;}@Overridepublic String getImageRootPath() {return null;}});// PipelinesPdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);// XML Workerfinal Charset charset = Charset.forName("UTF-8");XMLWorker worker = new XMLWorker(css, true);XMLParser p = new XMLParser(true ,worker,charset);try {p.parse(new ByteArrayInputStream(htmlStr.getBytes("UTF-8")),charset);}catch (Exception e){e.getMessage();}document.close();UploadFileDTO uploadFileDTO = fileService.fileUploadBytes(FileUtils.readFileToByteArray(new File(filePath)), companyId + "/contract/order/" + fileName);
return uploadFileDTO;}/*** 读取 HTML 文件* @return*/private static String readHtmlFile() {StringBuffer textHtml = new StringBuffer();try {File file = new File("D:\\test.html");BufferedReader reader = new BufferedReader(new FileReader(file));String tempString = null;// 一次读入一行,直到读入null为文件结束while ((tempString = reader.readLine()) != null) {textHtml.append(tempString);}reader.close();} catch (IOException e) {System.out.println("e"+e.toString());return null;}return textHtml.toString();}public static void main(String[] args) throws Exception {}
}
接下来是页眉页脚样式啥的支持类
import java.io.IOException;import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
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 PdfReportM1HeaderFooter extends PdfPageEventHelper {/*** 页眉*/public String header = "";/*** 文档字体大小,页脚页眉最好和文本大小一致*/public int presentFontSize = 12;/*** 文档页面大小,最好前面传入,否则默认为A4纸张*/public Rectangle pageSize = PageSize.A4;// 模板public PdfTemplate total;// 基础字体对象public BaseFont bf = null;// 利用基础字体生成的字体对象,一般用于生成中文文字public Font fontDetail = null;/**** Creates a new instance of PdfReportM1HeaderFooter 无参构造方法.**/public PdfReportM1HeaderFooter() {}/**** Creates a new instance of PdfReportM1HeaderFooter 构造方法.** @param yeMei* 页眉字符串* @param presentFontSize* 数据体字体大小* @param pageSize* 页面文档大小,A4,A5,A6横转翻转等Rectangle对象*/public PdfReportM1HeaderFooter(String yeMei, int presentFontSize, Rectangle pageSize) {this.header = yeMei;this.presentFontSize = presentFontSize;this.pageSize = pageSize;}public void setHeader(String header) {this.header = header;}public void setPresentFontSize(int presentFontSize) {this.presentFontSize = presentFontSize;}/**** TODO 文档打开时创建模板** @see PdfPageEventHelper#onOpenDocument(PdfWriter, Document)*/public void onOpenDocument(PdfWriter writer, Document document) {total = writer.getDirectContent().createTemplate(50, 50);// 共 页 的矩形的长宽高}/**** TODO 关闭每页的时候,写入页眉,写入'第几页共'这几个字。** @see PdfPageEventHelper#onEndPage(PdfWriter, Document)*/public void onEndPage(PdfWriter writer, Document document) {try {if (bf == null) {bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);}if (fontDetail == null) {fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体}} catch (DocumentException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}// 1.写入页眉ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, new Phrase(header, fontDetail), document.left(), document.top() + 20, 0);// 2.写入前半部分的 第 X页/共int pageS = writer.getPageNumber();String foot1 = "第 " + pageS + " 页 /共";Phrase footer = new Phrase(foot1, fontDetail);// 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = lenfloat len = bf.getWidthPoint(foot1, presentFontSize);// 4.拿到当前的PdfContentBytePdfContentByte cb = writer.getDirectContent();//自己增加的/*if(pageS==1){Phrase footerLeft = new Phrase("978-1-4799-0530-031.00 ©2013 IEEE", fontDetail);ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, footerLeft, document.left(), document.bottom() - 20, 0);}
*/// 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F 再给偏移20F适合人类视觉感受,否则肉眼看上去就太偏左了 ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了;注意Y轴是从下往上累加的,最上方的Top值是大于Bottom好几百开外的。ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, footer, (document.rightMargin() + document.right() + document.leftMargin() - document.left() - len) / 2.0F + 20F, document.bottom() - 20, 0);// 6.写入页脚2的模板(就是页脚的Y页这俩字)添加到文档中,计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F + len , y 轴和之前的保持一致,底边界-20cb.addTemplate(total, (document.rightMargin() + document.right() + document.leftMargin() - document.left()) / 2.0F + 20F, document.bottom() - 20); // 调节模版显示的位置}/**** TODO 关闭文档时,替换模板,完成整个页眉页脚组件** @see PdfPageEventHelper#onCloseDocument(PdfWriter, Document)*/public void onCloseDocument(PdfWriter writer, Document document) {// 7.最后一步了,就是关闭文档的时候,将模板替换成实际的 Y 值,至此,page x of y 制作完毕,完美兼容各种文档size。total.beginText();total.setFontAndSize(bf, presentFontSize);// 生成的模版的字体、颜色String foot2 = " " + (writer.getPageNumber()) + " 页";total.showText(foot2);// 模版显示的内容total.endText();total.closePath();}
}
4到这就完成了,测试一下
UploadFileDTO uploadFileDTO = new UploadFileDTO() ;
try {
uploadFileDTO = contractPdfUtil.writeToOutputStreamAsPDF(ro.getCompanyId(), templateEmailDTO.getSubject(), templateEmailDTO.getContent());
} catch (Exception exception) {
exception.printStackTrace();
}