文章目录
- 生成长图
- wkhtmltopdf介绍
- 服务器端生成长图(用于分享)
生成长图
- wkhtmltopdf(命令访问)
- wkhtmltopdf url file
- wkhtmltoimage url file
- java(java语言访问)
- Runtime.getRuntime().exec()
wkhtmltopdf介绍
1、安装wkhtmltopdf,添加环境变量
2、使用命令
html转pdf文件命令:wkhtmltopdf url file
html转图片:wkhtmltoimage url file
html转图片并压缩:wkhtmltoimage --quality 75 url file
3、java中使用wkhtmltopdf(注意是异步执行)
Runtime.getRuntime().exec(cmd) 服务器把定义的cmd 命令交给操作系统后,便继续向下执行了。即是异步的。
package com.nowcoder.community;
import java.io.IOException;
public class WkTests {
public static void main(String[] args) {
String cmd = "d:/work/wkhtmltopdf/bin/wkhtmltoimage --quality 75 https://www.nowcoder.com d:/work/data/wk-images/3.png";
try {
Runtime.getRuntime().exec(cmd);
System.out.println("ok.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器端生成长图(用于分享)
1、自定义配置。主要是定义wkhtmltopdf 命令所在文件,以及生成的长图存放文件
application.properties 文件
# wk
wk.image.command=d:/JavaWork/wkhtmltopdf/bin/wkhtmltoimage
wk.image.storage=d:/JavaWork/data/wk-images
2、检查并创建目录
@Configuration
public class WkConfig {
private static final Logger logger = LoggerFactory.getLogger(WkConfig.class);
@Value("${wk.image.storage}")
private String wkImageStorage;
@PostConstruct
public void init() {
// 创建WK图片目录
File file = new File(wkImageStorage);
if (!file.exists()) {
file.mkdir();
logger.info("创建WK图片目录: " + wkImageStorage);
}
}
}
若存放 file 的路径不存在,wkhtmltopdf不会自动创建。所以写一个配置类,并写一个初始化方法用来创建WK图片目录。服务器启动时,Spring会认为 WkConfig是配置类,先对其进行实例化,自动调用 init()
3、将指定 url 生成长图,用于分享
ShareController.java
@Controller
public class ShareController implements CommunityConstant {
private static final Logger logger = LoggerFactory.getLogger(ShareController.class);
@Autowired
private EventProducer eventProducer;
@Value("${community.path.domain}")
private String domain;
@Value("${server.servlet.context-path}")
private String contextPath;
@Value("${wk.image.storage}")
private String wkImageStorage;
@RequestMapping(path = "/share", method = RequestMethod.GET)
@ResponseBody
public String share(String htmlUrl) {
// 文件名
String fileName = CommunityUtil.generateUUID();
// 异步生成长图
Event event = new Event()
.setTopic(TOPIC_SHARE)
.setData("htmlUrl", htmlUrl)
.setData("fileName", fileName)
.setData("suffix", ".png");
eventProducer.fireEvent(event);
// 返回访问路径
Map<String, Object> map = new HashMap<>();
map.put("shareUrl", domain + contextPath + "/share/image/" + fileName); // [http://localhost:8080/community]/share/image/XXX.png
return CommunityUtil.getJSONString(0, null, map);
}
}
A、share 方法是用来生成长图的,并返回一个json字符串,如果成功,则code=0,分享url即是json中"shareUrl"的值。
1)生成图片是异步的方式,使用kafka
在 消费TOPIC_SHARE 方法里,使用 wkhtmltopdf 生成长图,并放在指定的本机文件夹中。
// 消费分享事件A
@KafkaListener(topics = TOPIC_SHARE)
public void handleShareMessage(ConsumerRecord record) {
if (record == null || record.value() == null) {
logger.error("消息的内容为空!");
return;
}
Event event = JSONObject.parseObject(record.value().toString(), Event.class);
if (event == null) {
logger.error("消息格式错误!");
return;
}
String htmlUrl = (String) event.getData().get("htmlUrl");
String fileName = (String) event.getData().get("fileName");
String suffix = (String) event.getData().get("suffix");
String cmd = wkImageCommand + " --quality 75 "
+ htmlUrl + " " + wkImageStorage + "/" + fileName + suffix;
try {
Runtime.getRuntime().exec(cmd);
logger.info("生成长图成功: " + cmd);
} catch (IOException e) {
logger.error("生成长图失败: " + e.getMessage());
}
}
B、用户访问 “shareUrl” 即可获取长图(即访问 [http://localhost:8080/community]/share/image/XXX.png 时,调用了 getShareImage 方法)
// 获取长图
@RequestMapping(path = "/share/image/{fileName}", method = RequestMethod.GET)
public void getShareImage(@PathVariable("fileName") String fileName, HttpServletResponse response) {
if (StringUtils.isBlank(fileName)) {
throw new IllegalArgumentException("文件名不能为空!");
}
response.setContentType("image/png"); //
File file = new File(wkImageStorage + "/" + fileName + ".png"); //本地 d:/JavaWork/data/wk-images/XXX.png
try {
OutputStream os = response.getOutputStream(); // 输出流,将文件写入 respone
FileInputStream fis = new FileInputStream(file); // 输入流,读取文件
byte[] buffer = new byte[1024];
int b = 0;
while ((b = fis.read(buffer)) != -1) {
os.write(buffer, 0, b);
}
} catch (IOException e) {
logger.error("获取长图失败: " + e.getMessage());
}
}
总结:
1、使用配置文件,设置 WK图片目录,域名,项目名。使用配置类,在加载时初始化,创建WK图片目录
2、用户访问 path = “/share?htmlUrl=…” 时,会使用kafka异步调用 WK 命令,将 htmlUrl 网页生成长图,操作成功会返回一个新的 shareUrl路径
3、用户访问shareUrl路径,即从服务器本地上下载了生成的长图