0


springboot 动态导出pdf

springboot 动态导出pdf

原理是通过freemarker插入数据到html模版里面,html你就叫前端帮你写好,他不写你就告诉你主管让他叫他写,你只管往预留的位置插入数据就行,然后通过itextpdf会将准备好html文件转成PDF。

1、准备依赖

<!--下载pdf begin--><dependency><groupId>com.itextpdf</groupId><artifactId>html2pdf</artifactId><version>4.0.3</version></dependency><!-- freemarker模版 --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.30</version></dependency><!--下载pdf end-->

2、准备html模版

<html><head><metacharset="UTF-8"><style>.main-container{font-family: SF-UI-Text-Regular;width: 21cm;margin: 0 auto;padding: 20px;}.float-left{float: left;}.float-right{float: right;}.padding-left-right{padding-left: 20px;padding-right: 20px;}.margin-left-right{margin-left: 20px;margin-right: 20px;}.section{/*border: 3px dashed #CCC;*//*padding: 20px;*/border-Top: 2px dashed #D3D3D3;padding-Top: 13px;margin-bottom: 16px;margin-Top: 20px;}.section-details p{color: #126089;/*font-size: 16px;*/}.grouper{overflow: hidden;}.grid-50{width: 50%;}@font-face{font-family:'SF-UI-Text-Regular';src:url("https://s3-ap-southeast-1.amazonaws.com/content.staging.whitecoat.global/PDF/Templates/fonts/SF-UI-Text-Regular.otf");font-style: normal;}h1{font-size: 22px;font-family:'SF-UI-Text-Regular';}.h1-main{margin-top: 90px;}p{margin: 0 0 10px 0;font-family:'SF-UI-Text-Regular';font-size: 12px;}.p-spec{color: #149a9a;font-weight: bold;}table, th, td{padding: 5px;border-collapse: collapse;}th, td{border: 1px solid #D3D3D3;}.margin-b-30{margin-bottom: 30px;}.row:after{content:"";display: table;clear: both;}.column-4{float: left;width: 33.33%;padding: 10px;}.column-8{float: left;width: 66.66%;padding: 10px;}*{box-sizing: border-box;font-size: 12px;}</style></head><body><divclass="main-container"><divstyle="background-color: #fff"><divclass="grouper main-header grouper padding-left-right"style="padding-top: 20px"><divclass="margin-b-30 row"><divclass="column-4"><imgstyle="max-width:90%"src="https://s3-ap-southeast-1.amazonaws.com/content.staging.whitecoat.global/PDF/Templates/Images/WhiteCoat_Tax_Invoice.png"></div><divclass="column-4">
                    WhiteCoat Holdings Pte Ltd. <br/>
                    Clinic Licence No.: 18M0119/01/182 <br/>
                    201 Henderson Road #05-11/12 <br/>
                    Apex @ Henderson <br/>
                    Singapore 159545 <br/></div><divclass="column-4">
                    GST Reg. No: 201610235E <br/>
                    T: +65 6909 6909 <br/>
                    F: +65 6909 6909 <br/>
                    E: [email protected] <br/><astyle="text-decoration: none;"href="https://whitecoat.com.sg/">whitecoat.com.sg</a></div></div></div><divclass="main-body"><divclass="grouper"><divclass="grouper margin-left-right row"style="border-Top: 1px solid #D3D3D3;padding-top:20px;"><divclass="column-4">
                        Name: <br/>
                        ${data.name!} <br/><br/>
                        NRIC/FIN/Passport No: <br/>
                        ${data.idNo!}
                    </div><divclass="column-8">
                        Invoice No.: <br/>
                        ${data.invoiceNo!} <br/><br/>
                        Invoice Date: <br/>
                        ${data.invoiceDateStr!} <br/><br/><i>This is a computer generated invoice. No signature is required.</i></div></div><divclass="grouper margin-left-right"style="border-Top: 1px solid #D3D3D3;padding-top:20px;"><table><tr><th>S/N</th><thcolspan="2">Description</th><thstyle="border:1px solid #D3D3D3;">Amount</th></tr><tr><tdstyle="width:30px;text-align:center;">1</td><tdstyle="width:550px;border-right: none">
                                Medication <br/><#listdata.medicationListasitem>
                                    ${item.productName!} <br/></#list><i><br/>Subtotal</i></td><tdstyle="text-align:right;border-left: none">
                                Quantity <br/><#listdata.medicationListasitem>
                                    ${item.quantity!} <br/></#list><istyle="color:#fff"><br/>Subtotal</i></td><tdstyle="width:200px;text-align:right"><br/><#listdata.medicationListasitem>
                                    $${item.amount!} <br/></#list><br/><i>${data.subtotal!}</i></td></tr><tr><tdstyle="text-align:center;">2</td><tdcolspan="2">Administrative charges</td><tdstyle="text-align:right">$${data.adminCharge!}</td></tr><tr><tdcolspan="3"style="text-align:right;border-bottom: none;border-left: none">
                                Subtotal(Excluding GST)
                            </td><tdstyle="text-align:right">$${data.subtotalExcludingGST!}</td></tr><tr><tdcolspan="3"style="text-align:right;;border-bottom: none;border-top: none;border-left: none">
                                GST(${data.tax!}%)
                            </td><tdstyle="text-align:right">$${data.GST!}</td></tr><tr><tdcolspan="3"style="text-align:right;border-top: none;border-left: none;border-bottom: none">
                                Total(Including GST)
                            </td><tdstyle="text-align:right">$${data.totalIncludingGST!}</td></tr></table></div><divclass="grouper margin-left-right float-left"style="padding-bottom:20px;padding-top:20px"><span>
                            Bank remittance details for payment by Bank Telegraphic <br/>
                            Transfer in Singapore Dollars to:<br/>
                            Name of Bank: United Overseas Bank Ltd. Holland Branch<br/>
                            Account Name: Whitecoat Holdings Pte Ltd.<br/>
                            Account No: 341-308-316-6<br/>
                            Bank Code: 7375<br/>
                            Branch Code: 020<br/>
                            Bank Swift Code: UOVBSGSG
                        </span></div></div></div></div></body></html>

3、下载代码

@ApiOperation(value ="下载pdf")@GetMapping("downloadPDF/staffPurchase")publicResponseResultdownload(String id,HttpServletResponse response)throwsException{StaffPurchasePDFVo data = staffPurchaseMapper.getStaffPurchasePDFData(id);HashMap<String,Object> mapData =Maps.newHashMap();
        mapData.put("data", data);long timeMillis =System.currentTimeMillis();String templateContent =HtmlUtils.getTemplateContent("Staff_Purchase_Receipt.ftl", mapData);HtmlUtils.html2Pdf(response, templateContent, timeMillis +"");returnResponseResult.success();}

4、htmlutils代码

importcom.itextpdf.html2pdf.ConverterProperties;importcom.itextpdf.html2pdf.HtmlConverter;importcom.itextpdf.layout.font.FontProvider;importfreemarker.template.Configuration;importfreemarker.template.Template;importlombok.extern.slf4j.Slf4j;importorg.springframework.ui.freemarker.FreeMarkerTemplateUtils;importorg.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;importjavax.servlet.ServletOutputStream;importjavax.servlet.http.HttpServletResponse;importjava.io.FileOutputStream;importjava.io.IOException;importjava.net.URISyntaxException;importjava.net.URL;importjava.util.Map;importjava.util.Objects;@Slf4jpublicclassHtmlUtils{/**
     * @return
     * @throws Exception
     */publicstaticStringgetTemplateDirectory(){ClassLoader classLoader =HtmlUtils.class.getClassLoader();URL resource = classLoader.getResource("templates");try{returnObjects.requireNonNull(resource).toURI().getPath();}catch(URISyntaxException e){
            log.error("获取模板文件夹失败,{}", e);}returnnull;}/**
     * 获取模板内容
     *
     * @param templateName 模板文件名
     * @param paramMap     模板参数
     * @return
     * @throws Exception
     */publicstaticStringgetTemplateContent(String templateName,Map<String,Object> paramMap)throwsException{Configuration config =ApplicationContextUtil.getBean(FreeMarkerConfigurer.class).getConfiguration();
        config.setDefaultEncoding("UTF-8");Template template = config.getTemplate(templateName,"UTF-8");returnFreeMarkerTemplateUtils.processTemplateIntoString(template, paramMap);}/**
     * HTML 转 PDF
     *
     * @param content html内容
     * @param outPath 输出pdf路径
     * @return 是否创建成功
     */publicstaticbooleanhtml2Pdf(String content,String outPath){try{ConverterProperties converterProperties =newConverterProperties();
            converterProperties.setCharset("UTF-8");FontProvider fontProvider =newFontProvider();
            fontProvider.addSystemFonts();
            converterProperties.setFontProvider(fontProvider);HtmlConverter.convertToPdf(content,newFileOutputStream(outPath), converterProperties);}catch(Exception e){
            log.error("生成模板内容失败,{}", e);returnfalse;}returntrue;}/**
     * HTML 转 PDF
     *
     * @param content html内容
     * @return PDF字节数组
     */publicstaticvoidhtml2Pdf(HttpServletResponse response,String content,String filename)throwsIOException{
        response.setHeader("Content-Type","application/octet-stream");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition","attachment;filename="+filename+".pdf");try(ServletOutputStream outputStream = response.getOutputStream()){ConverterProperties converterProperties =newConverterProperties();
            converterProperties.setCharset("UTF-8");FontProvider fontProvider =newFontProvider();
            fontProvider.addSystemFonts();
            converterProperties.setFontProvider(fontProvider);HtmlConverter.convertToPdf(content, outputStream, converterProperties);}catch(Exception e){
            log.error("生成 PDF 失败,{}", e);}}}

ApplicationContextUtil代码、

importorg.springframework.beans.BeansException;importorg.springframework.boot.autoconfigure.AutoConfigureOrder;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;importorg.springframework.context.annotation.Configuration;@Configuration@AutoConfigureOrder(-1)publicclassApplicationContextUtilimplementsApplicationContextAware{privatestaticApplicationContext applicationContext =null;publicstaticObjectgetBeanByName(String beanName){if(applicationContext ==null){returnnull;}return applicationContext.getBean(beanName);}publicstatic<T>TgetBean(Class<T> type){return applicationContext.getBean(type);}@OverridepublicvoidsetApplicationContext(ApplicationContext applicationContext)throwsBeansException{ApplicationContextUtil.applicationContext = applicationContext;}}

5、freemarker的基本语法

https://developer.aliyun.com/article/942606

6、注意

如果css写了具体的大小比如width: 21cm;,那么下载出来的pdf会因为超出边界被截取,别写。

标签: spring boot pdf 后端

本文转载自: https://blog.csdn.net/qq_38899062/article/details/135897354
版权归原作者 Ayu大象 所有, 如有侵权,请联系我们删除。

“springboot 动态导出pdf”的评论:

还没有评论