当前位置: 首页 > news >正文

呼和浩特做网站的朝阳网站建设 慈云寺

呼和浩特做网站的,朝阳网站建设 慈云寺,免费的行情网站ifind是,深圳市 交易建设中心网站最近公司有个需求#xff0c;就是想根据一个模板生成一个pdf文档#xff0c;当即我就想到了freemarker这个远古老东西#xff0c;毕竟freemarker在模板渲染方面还是非常有优势的。 准备依赖#xff1a; dependencygroupIdorg.springframework.boot/gr…最近公司有个需求就是想根据一个模板生成一个pdf文档当即我就想到了freemarker这个远古老东西毕竟freemarker在模板渲染方面还是非常有优势的。 准备依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-freemarker/artifactId/dependencydependencygroupIdcom.itextpdf/groupIdartifactIdhtml2pdf/artifactIdversion3.0.5/version/dependency!--pdf 支持中文(默认不支持)--dependencygroupIdcom.itextpdf/groupIdartifactIditext-asian/artifactIdversion5.2.0/version/dependencydependencygroupIdcom.itextpdf/groupIdartifactIditextpdf/artifactIdversion5.5.13/version/dependency我这里不想选freemarker版本直接用spring集成的省事。 配置一下freemarker的配置 import freemarker.template.Configuration; import freemarker.template.TemplateExceptionHandler; import org.springframework.context.annotation.Bean; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Component;import java.io.IOException;Component org.springframework.context.annotation.Configuration public class FreemarkerConfig {// 我这里为了省事不想创建那么多的Configuration而且创建Configuration太多不好Bean(name cfg)public Configuration freemarkerConfigurer() throws IOException {// 选择版本不同版本对不同的模板语法或者模板转换也会有差异如果你css 样式比较新建议选高版本准没错Configuration cfg new Configuration(Configuration.VERSION_2_3_22);// 选择你存放模板的位置final ClassPathResource classPathResource new ClassPathResource(templates);cfg.setDirectoryForTemplateLoading(classPathResource.getFile());cfg.setDefaultEncoding(UTF-8);// 模板异常处理cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);return cfg;} }然后我们准备下我们的ftl模板【freemarker的模板文件】----pdf.ftl freemarker框架类似于beetl、thymeleaf、jsp、Velocity等模板引擎 JSP就不用说了吧基本上开发Java的基本上都会了解开发过 !doctype html html langen headmeta charsetUTF-8meta nameviewportcontentwidthdevice-width, user-scalableno, initial-scale1.0, maximum-scale1.0, minimum-scale1.0meta http-equivX-UA-Compatible contentieedgetitleDocument/title /head style.logo {width: 320px;height: 80px;}.user-info {padding: 10px 10px;background: RGB(221, 235, 247);}.label {width: 150px;padding: 0 20px 0 0;text-align: left;}.time {width: 100px;margin-right: 10px;text-align: center;}.label, .time {display: inline-block;}.range-time {margin: 20px 0;}.table-data {width: 100%;}table{border-collapse: collapse;}.header th {text-align: left;height: 50px;}.divider-line {margin: 20px 0;height: 3px;background: #000;}.desc {padding: 15px 10px;}.date {width: 100px;}.fee {width: 50px;}.name {width: 140px;}.name, .fee, .date {padding: 0 10px;}.download-date {text-align: right;}.bottom-footer-tip {width: 100%;margin-top: 300px;font-size: 12px;transform: scale(.9);} /style bodydiv classdownload-dateDownload on 2022/2/2/div div classrange-timespan classtime${startTime}/spanspanto/spanspan classtime${endTime}/span /divtable classtable-datatr classheaderthDate/ththName/ththdesc/ththfee/th/trtr classdivider-lineth/thth/thth/thth/th/tr#list list as itemtrtd classdate${item.date}/tdtd classname${item.name}/tdtd classdescdiv${item.desc}/div/tdtd classfee${item.fee}/td/tr/#listtr classdivider-lineth/thth/thth/thth/th/tr /table /body /html这里ftl的语法我就不多做解释了我这里附上freemarker的官方文档感兴趣的自己去学习一下。 然后准备下我们的代码处理逻辑 首先是PDF实体数据 import lombok.Data;import java.util.List;Data public class PDFData {private String logo;private String name;private String address;private String startTime;private String endTime;private ListTableData list; }然后是关联table数据 import lombok.Data;Data public class TableData {private String date;private String desc;private String name;private String fee; }然后我们处理我们处理逻辑的代码 import com.alibaba.fastjson.JSONObject; import com.example.web.pojo.TableData; import com.example.web.pojo.PDFData; import com.itextpdf.html2pdf.ConverterProperties; import com.itextpdf.html2pdf.HtmlConverter; import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider; import com.itextpdf.kernel.colors.DeviceRgb; import com.itextpdf.kernel.font.PdfFontFactory; import com.itextpdf.kernel.geom.PageSize; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfPage; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.layout.Document; import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.font.FontProvider; import com.itextpdf.layout.property.TextAlignment; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.TemplateExceptionHandler; import org.springframework.stereotype.Component;import javax.annotation.Resource; import java.io.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*;Component public class FreemarkerExecution {// 准备下字体文件private static String FONT ./src/main/resources/templates/AlibabaPuHuiTi-3-65-Medium.ttf;// 后续转pdf时的配置private static ConverterProperties converterProperties new ConverterProperties();private static String base64LogoData null;{FontProvider dfp new DefaultFontProvider();//添加字体库dfp.addFont(FONT);//设置解析属性converterProperties.setFontProvider(dfp);converterProperties.setCharset(utf-8);try {// 有一个logo处理因为一般服务器渲染的话一般建议将部分图片处理成base64然后放进来或者大家看看其他的方式base64LogoData imgToBase64(new FileInputStream(./src/main/resources/templates/logo.png));} catch (FileNotFoundException e) {e.printStackTrace();}}Resource(name cfg)private Configuration configuration;// 普通处理逻辑public void converterHTML() {// 这个会将处理后的html语法输出至 命令行窗口可以手动创建一个html文件然后把结果复制进去直接打开查看try (Writer out new OutputStreamWriter(System.out)) {// 获取数据final PDFData pdfData getData();Template temp configuration.getTemplate(pdf.ftl);// 直接写出文件temp.process(pdfData, out);} catch (IOException e) {e.printStackTrace();} finally {}}private void writeToPDF(Template template, MapString, Object dataModel) {try {final File file new File(D:/pdf/test.html);template.process(dataModel, new OutputStreamWriter(new FileOutputStream(file)));final File pdfFile new File(D:/pdf/test.pdf);HtmlConverter.convertToPdf(file, pdfFile, converterProperties);PdfReader reader new PdfReader(new File(D:/pdf/test.pdf));PdfWriter writer new PdfWriter(new FileOutputStream(D:/pdf/test_1.pdf));PdfDocument pdfDocument new PdfDocument(reader, writer);// 页大小final PageSize pageSize pdfDocument.getDefaultPageSize();// 页数final int numberOfPages pdfDocument.getNumberOfPages();for (int i 1; i numberOfPages; i) {PdfPage page pdfDocument.getPage(i);final PdfDocument pdfDoc page.getDocument();final Document document new Document(pdfDoc);final Paragraph paragraph new Paragraph(Page i).setFont(PdfFontFactory.createFont(FONT)).setFontColor(new DeviceRgb(0, 0, 0)).setFixedPosition(i, 0, 10, pageSize.getWidth()).setFontSize(10).setTextAlignment(TextAlignment.CENTER);document.add(paragraph);}pdfDocument.close();reader.close();writer.close();} catch (Exception e) {e.printStackTrace();}}private PDFData getData() throws FileNotFoundException {PDFData data new PDFData();data.setName(重生之我是蔡徐坤);data.setAddress(蔡徐坤蔡徐坤喜欢唱跳rap篮球);data.setStartTime(01-Feb-22);data.setEndTime(28-Feb-22);data.setLogo(data:image/png;base64, base64LogoData);final LocalDateTime nowTime LocalDateTime.now();final ListTableData arr new ArrayList();for (int i 0; i 10; i) {final TableData tableData new TableData();tableData .setDesc(i % 2 0 ? 交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大 : 交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大交会毫不我交会毫不我哒哒哒哒哒哒多多多多多多多交会毫不我电话电话大);tableData .setName(蔡徐坤 i);tableData .setFee(1000 i );tableData .setDate(nowTime.plusDays(-i).format(DateTimeFormatter.ofPattern(YYYY/MM/dd)));arr.add(tableData);}data.setList(arr);return data;}private String imgToBase64(InputStream inputStream) {byte[] data null;try {data new byte[inputStream.available()];inputStream.read(data);inputStream.close();} catch (IOException e) {e.printStackTrace();}return Base64.getEncoder().encodeToString(data);} }这里会又有一个问题出现就是我们一般处理PDF的时候数据不可能一次性处理到内存中因为我们服务器内存等问题假如我们有100w数据肯定不能一次性查出来由此我们就需要批量处理这里我们可以将模板拆分开重复的数据放一个模板文件然后后续进行模板的组装。 首先我将一个ftl模板文件拆成了三个 header.ftl,content.ftl,footer.ftl,然后再由一个主的核心ftl模板来组装这几个模板。 思路准备上述模板文件然后渲染模板后继续解析成ftl模板文件然后读取选然后的ftl模板文件然后转成html最后通过html文件处理成pdf文件。 这里content.ftl是批量的数据因为不能一次读取大量数据所以这里content.ftl要单独处理一下。 Main.ftl !doctype html html langen headmeta charsetUTF-8meta nameviewportcontentwidthdevice-width, user-scalableno, initial-scale1.0, maximum-scale1.0, minimum-scale1.0meta http-equivX-UA-Compatible contentieedgetitleDocument/title /head style.logo {width: 320px;height: 80px;}.user-info {padding: 10px 10px;background: RGB(221, 235, 247);}.label {width: 150px;padding: 0 20px 0 0;text-align: left;}.time {width: 100px;margin-right: 10px;text-align: center;}.label, .time {display: inline-block;}.range-time {margin: 20px 0;}.table-data {width: 100%;}table {border-collapse: collapse;}.header th {text-align: left;height: 50px;}.divider-line {margin: 20px 0;height: 3px;background: #000;}.desc {padding: 15px 10px;}.date {width: 100px;}.name {width: 50px;}.fee{width: 140px;}.fee, .name , .date {padding: 0 10px;}.download-date {text-align: right;}.bottom-footer-tip {width: 100%;margin-top: 300px;font-size: 12px;transform: scale(.9);} /style body${headerPath} table classtable-datatr classheaderthDate/ththDesc/ththName/ththFee/th/trtr classdivider-lineth/thth/thth/thth/th/tr#list contentPathList as content${content}/#listtr classdivider-lineth/thth/thth/thth/th/tr /table ${footerPath}#--#include header.ftl-- #--#include content.ftl-- #--#include footer.ftl--/body /htmlheader.ftl img src${logo} classlogo div classdownload-dateDownload on 2022/2/2/div div classuser-infodivdiv classlabelUser:/divspan${name}/span/divdivdiv classlabelAddress:/divspan${address}/span/div /divdiv classrange-timespan classtime${startTime}/spanspanto/spanspan classtime${endTime}/span /divcontent.ftl #list list as itemtrtd classdate${item.date}/tdtd classdescdiv${item.desc}/div/tdtd classfee${item.fee}/tdtd classname${item.name}/td/tr/#list footer.ftl #list list as itemtrtd classdate${item.date}/tdtd classdescdiv${item.desc}/div/tdtd classfee${item.fee}/tdtd classname${item.name}/td/tr/#list 核心处理逻辑 void allTemplatesWriteToPDF() {// 所有子模板final ListString ftlNameList new ArrayList();try {// 读取对应的模板文件final Template template getTemplate(content.ftl);final Template headerTemplate getTemplate(header.ftl);final Template footerTemplate getTemplate(footer.ftl);final PDFData data getData();// 先处理头部和尾部headerTemplate.process(data, new FileWriter(D:/pdf/content/header.ftl));footerTemplate.process(data, new FileWriter(D:/pdf/content/footer.ftl));// mock 模拟数据库查询10次for (int i 0; i 10; i) {// 组装10条数据算上10次循环一共100条数据final PDFData pdfData getData();String fileName D:/pdf/content/content i .ftl;final FileWriter writer new FileWriter(fileName);// 存储最后框架模板的数据这里是存储了freemarker include 语法连接所有的需要组装的数据模板名称ftlNameList.add(#include \ fileName.substring(fileName.lastIndexOf(/) 1, fileName.lastIndexOf(.)) .ftl \/);// 生成对应的模板文档template.process(pdfData, writer);writer.flush();writer.close();}// 获取所有子模板final Configuration cdf new Configuration(Configuration.VERSION_2_3_22);cdf.setDirectoryForTemplateLoading(new File(D:/pdf/content));cdf.setDefaultEncoding(UTF-8);cdf.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);final Template mainTemplate getTemplate(main.ftl);final HashMapObject, Object map new HashMap();map.put(headerPath, #include \ header.ftl\/);map.put(contentPathList, ftlNameList);map.put(footerPath, #include \ footer.ftl\/);mainTemplate.process(map, new FileWriter(D:/pdf/content/main.ftl));final Template cdfTemplate cdf.getTemplate(main.ftl);cdfTemplate.process(null, new FileWriter(D:/pdf/content/main.html));final File pdfFile new File(D:/pdf/test_new.pdf);HtmlConverter.convertToPdf(new File(D:/pdf/content/main.html), pdfFile, converterProperties);PdfReader reader new PdfReader(pdfFile);PdfWriter writer new PdfWriter(new FileOutputStream(D:/pdf/test_new_1.pdf));PdfDocument pdfDocument new PdfDocument(reader, writer);// 页大小final PageSize pageSize pdfDocument.getDefaultPageSize();// 页数final int numberOfPages pdfDocument.getNumberOfPages();// 这里是处理页脚数据for (int i 1; i numberOfPages; i) {PdfPage page pdfDocument.getPage(i);final PdfDocument pdfDoc page.getDocument();final Document document new Document(pdfDoc);final Paragraph paragraph new Paragraph(Page i).setFont(PdfFontFactory.createFont(FONT)).setFontColor(new DeviceRgb(0, 0, 0)).setFixedPosition(i, 0, 10, pageSize.getWidth()).setFontSize(10).setTextAlignment(TextAlignment.CENTER);document.add(paragraph);}pdfDocument.close();reader.close();writer.close();} catch (IOException | TemplateException e) {e.printStackTrace();}}private Template getTemplate(String name) throws IOException {return configuration.getTemplate(name);}OK大概就这样剩下的大家自己去玩吧 解散
http://www.tj-hxxt.cn/news/232142.html

相关文章:

  • 湘潭找工作网站个人的网站建设的目的
  • 哪家成都公司做网站网页游戏平台排名前10名
  • 网站建设和网站开发的区别深圳手机网站公司
  • 网站添加属性物流网站的功能与特色
  • 网络营销做得好的产品什么网站做优化最好?
  • 做网站的联系方式免费培训机构
  • 淘宝客网站WordPress最新注册公司流程及费用
  • 网站设计网页首页介绍如何搭建微信公众号平台
  • 直播网站可以做毕设吗网页模板网站有那些
  • 沧州做网站哪家好网页设计ppt模板
  • 东莞整站排名苏州品牌网站建设
  • 织梦网站后台模板wordpress移动
  • pdf怎么做电子书下载网站买了域名怎么做网站
  • 中国工商银行网站建设WordPress勾选评论
  • 哈尔滨房地产型网站建设资源共享课程网站开发毕业设计
  • 兰州展柜公司网站建设邯郸市网站建设多少钱
  • 滴滴网站建设流程seo快排优化
  • 漳州市建设网站网店代运营具体做什么
  • 企业网站建设中有哪几个重要点青岛网站建设大全
  • 网站建设要不要学编码WordPress人物插件
  • 西安建网站哪家好企业网页如何制作
  • 网站建设的开发方式和费用wordpress导航字体大小
  • wordpress怎样更改文章阅读次数哈尔滨百度推广排名优化
  • 网站建设定制做ic哪些网站好做
  • 企业网站建设费用详情网站建设什么公司专业
  • 网站需求说明东莞设计网站推荐
  • 网站备案点不进去一般做网站服务器的cpu
  • 网站设计公司-信科网络wordpress支付集成
  • 网站管理助手ftp连接不上网站建设发展趋势
  • 建设维护网站未签订合同学做网站难不难