👉 这是一个或许对你有用的社群
🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:
- 《项目实战(视频)》:从书中学,往事上“练”
- 《互联网高频面试题》:面朝简历学习,春暖花开
- 《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题
- 《精进 Java 学习指南》:系统学习,互联网主流技术栈
- 《必读 Java 源码专栏》:知其然,知其所以然
👉这是一个或许对你有用的开源项目
国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。
功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:
- Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
- Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
- 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本
这个文档太复杂了,还要导出pdf?
废话不多说直接进入正题,首先分析生成pdf场景及生成内容,考虑复用性和维护难度是我们当前开发工作的第一要务!
下面是调研的几个主要方案:
使用方式:
方案优缺点:
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
使用方式:
方案优缺点:
这可能是由于doc4J迭代问题无法保证新元素的支持,导出结果比较奔放。。。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
使用方式:
方案优缺点:
受限于调试前期需要的修修改改,模板能给人整吐了,所以才有了下一个方案。
使用方式:
方案优缺点:
这个方案是综合以上多次踩坑的结果,结果是显而易见的。
浅浅来一点代码,省的大家到处找
` <dependencies>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.0.3</version>
</dependency>
<dependency>
<groupId>binarta.oss</groupId>
<artifactId>groovy-template-enginex-freemarker</artifactId>
<version>0.1.3</version>
</dependency>
<dependencies>
`
`import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil;
import com.google.common.collect.Lists;
import com.itextpdf.text.pdf.BaseFont;
import freemarker.cache.ByteArrayTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.SneakyThrows;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
public class HtmlToPdfUtil {
private static final ByteArrayTemplateLoader TEMPLATE_LOADER = new ByteArrayTemplateLoader();
// 导入需要字体库的位置哦;simsun 为 宋体
public static final String FRONT_PATH = "/usr/share/fonts/simsun.ttc";
/**
* 看明白的话只用这个方法就够
*/
public static ByteArrayOutputStream htmlToPdf(String templateName, Supplier<byte[]> loadTemplateSupplier, Map<String, Object> modeViewMap) {
String html = xmlFormat(templateName, loadTemplateSupplier, modeViewMap);
return htmlToPdf(html);
}
@SneakyThrows
public static ByteArrayOutputStream htmlToPdf(String htmlStr) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(htmlStr);
ITextFontResolver resolver = renderer.getFontResolver();
//添加字体,解决中文不显示的问题
resolver.addFont(FRONT_PATH, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.layout();
renderer.createPDF(outputStream);
return outputStream;
}
public static String xmlFormat(String templateName, Supplier<byte[]> loadTemplateSupplier, Map<String, Object> modeViewMap) {
if (Objects.isNull(TEMPLATE_LOADER.findTemplateSource(templateName))) {
synchronized (TEMPLATE_LOADER) {
if (Objects.isNull(TEMPLATE_LOADER.findTemplateSource(templateName))) {
TEMPLATE_LOADER.putTemplate(templateName, loadTemplateSupplier.get());
}
}
}
return xmlFormat(templateName, modeViewMap);
}
@SneakyThrows
public static String xmlFormat(String templateName, Map<String, Object> modeViewMap) {
Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
// 指定FreeMarker模板文件的位置
cfg.setTemplateLoader(TEMPLATE_LOADER);
// 设置模板的编码格式
cfg.setEncoding(Locale.CHINA, Charset.defaultCharset().name());
// 获取模板文件 template
Template template = cfg.getTemplate(templateName, Charset.defaultCharset().name());
StringWriter stringWriter = new StringWriter();
BufferedWriter writer = new BufferedWriter(stringWriter);
template.process(modeViewMap, writer);
return stringWriter.toString();
}
}
`
解决这个问题的核心思路方案其实一直没变,变化的只是工具,一定要思路清晰!
欢迎加入我的知识星球,全面提升技术能力。
👉 加入方式,“长按”或“扫描”下方二维码噢:
星球的内容包括:项目实战、面试招聘、源码解析、学习路线。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (^__^)
原网址: 访问
创建于: 2024-04-22 10:49:30
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论