前几天因为业务需求用到了这个,感觉蛮方便又好用,故写此文章帮助自己remember一下,以后说不定还用得上呢
本文会分别介绍在window系统和linux系统上如何使用 JAVA + PhantomJs 实现根据网页地址转换成图片
Linux 系统(Centos)
1. 先下载相应版本的phantomjs,上传到Linux系统
如果你的linux系统可以联网,也可直接在线下载
2. 解压(此处版本号用xxx代替)
tar -xvf phantomjs-xxxx.tar.bz2
3. 将解压的软件移到相应位置(位置可随意选择,此处版本号用xxx代替)
sudo mv phantomjsxxx /usr/local/src/phantomjs
4. 创建软连接到系统环境(类似window上的快捷方式),这样就可以使用phantomjs命令了
sudo ln -sf /usr/local/src/phantomjs/bin/phantomjs /usr/local/bin/phantomjs
/usr/local/bin是Linux系统给用户放置自己的可执行程序的目录
5. 给软连接添加执行的权限
sudo chmod u+x,o+x /usr/local/bin/phantomjs
6. 校验是否能正常使用
phantomjs --version
如果返回版本信息则表示安装成功,如果出现错误如下:
phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file:
表示缺少依赖环境,尝试安装以下环境解决
yum install freetype-devel fontconfig-devel
另外,截图中如果中文未显示,是因为linux下缺失中文字体,centos安装中文字体命令如下
yum install bitmap-fonts bitmap-fonts-cjk
完成以上步骤则表示phantomjs的安装搞定!
7. 上传js文件至linux系统
js文件内容如下:(要记住js文件的路径)
var page = require('webpage').create(),
system = require('system'),
address, output, size;
if (system.args.length < 3 || system.args.length > 5) {
phantom.exit(1);//凡是结束必须调用。否则phantomjs不会停止
} else {
address = system.args[1];//传入url地址
output = system.args[2];//输出图片的地址
page.viewportSize = { width: 530, height: 940 };//自定义截图宽高
if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
size = system.args[3].split('*');
page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
: { format: system.args[3], orientation: 'portrait', margin: '1cm' };
} else if (system.args.length > 3 && system.args[3].substr(-2) === "px") {
size = system.args[3].split('*');
if (size.length === 2) {
pageWidth = parseInt(size[0], 10);
pageHeight = parseInt(size[1], 10);
page.viewportSize = { width: pageWidth, height: pageHeight };
page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight };
} else {
console.log("size:", system.args[3]);
pageWidth = parseInt(system.args[3], 10);
pageHeight = parseInt(pageWidth * 3/4, 10); // it's as good an assumption as any
console.log ("pageHeight:",pageHeight);
page.viewportSize = { width: pageWidth, height: pageHeight };
}
}
if (system.args.length > 4) {
page.zoomFactor = system.args[4];
}
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit(1);
} else {
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 5000);
}
});
}
8. java 代码中调用phantomjs
这里我是封装了个工具类,然后业务层再调用工具类来调用phantomjs
package org.lin.project.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 根据网页地址转换成图片
*/
public class PhantomTools {
private static String BLANK = " ";
// 执行cmd命令
public static String cmd(String imgagePath, String url,String binPath,String jsPath) {
return binPath + BLANK + jsPath + BLANK + url + BLANK + imgagePath;
}
//关闭命令
public static void close(Process process, BufferedReader bufferedReader) throws IOException {
if (bufferedReader != null) {
bufferedReader.close();
}
if (process != null) {
process.destroy();
process = null;
}
}
/**
* @param url 要截取的网页地址
* @param tempPath 生成图片的存放地址
* @param binPath phantomjs插件安装地址
* @param jsPath js文件引入地址
* @throws IOException
*/
public static String printUrlScreen2jpg(String url, String tempPath,String binPath,String jsPath) throws IOException{
String imgName = System.currentTimeMillis() + ".png";
String imagePath = tempPath + "/" + imgName;//图片路径
//Java中使用Runtime和Process类运行外部程序
Process process = Runtime.getRuntime().exec(cmd(imagePath,url,binPath,jsPath));
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String tmp = "";
while ((tmp = reader.readLine()) != null) {
close(process,reader);
}
System.out.println("success");
return imgName;
}
}
9. 业务代码
这里我根据业务需求,是写了个定时器来定时调用工具类将网页转换成图片再将图片上传到服务器并保存图片地址到数据库,贴出部分代码仅供大家参考,具体各位根据自己业务需求再修改
配置文件 xx.properties
# phantomjs 插件安装地址
phantomjs.binPath=/opt/phantomjs-2.1.1/bin/phantomjs
# js文件存放地址
phantomjs.jsPath=/opt/phantomjs-2.1.1/phantomjs.js
# 要截取的网页url
phantomjs.urlStr=http://xxx:8080/xxx.html?xxxId=
# 生成图片存放地址
phantomjs.imgUrl=/opt/phantomImg
java 代码
@JobHandler(value = "CreateTestImgHandler")
@Service
public class CreateTestImgHandler extends IJobHandler {
@Autowired
private FileSDKClient fileSDKClient;
@Autowired
private TestService testService;
@Value("${phantomjs.urlStr}")
private String urlStr;//网页url
@Value("${phantomjs.binPath}")
private String binPath;// 插件引入地址
@Value("${phantomjs.jsPath}")
private String jsPath;// js引入地址
@Value("${phantomjs.imgUrl}")
private String imgUrl;// 生成图片地址
@Override
public ReturnT<String> execute(String s) throws Exception {
XxlJobLogger.log("生成XX图片start..." + DateUtil.date2String(new Date()));
///-------业务代码--------
List<Test> testList = testService.findByImg();
for(Test test:testList ){
//生成图片
String url = urlStr + test.getId();//拼接url(我这里是动态页面)
String nameStr = PhantomTools.printUrlScreen2jpg(url,imgUrl,binPath,jsPath);
String name = imgUrl + "/" + nameStr;
//上传图片
byte[] bytes = ImgUtil.image2Bytes(name);
QFile file = new QFile();
file.setContent(bytes);
file.setName("test");
file.setFileType(".png");
String uid = fileSDKClient.saveToUid(file);
//保存图片地址到数据库
test.setXXImg("/" + uid);
testService.update(test);
}
///---------------
XxlJobLogger.log("生成XX图片end..." + DateUtil.date2String(new Date()));
ReturnT<String> returnT = new ReturnT<String>(200, "执行成功!");
return returnT;
}
}
window系统
window系统上使用比较简单,下载解压即可在java程序中调用了。
1.先下载安装phantomjs
选择相应的系统版本下载解压即可(记住安装路径,后面需要用到)。如果你想直接在cmd上使用phantomjs的命令,请把bin下面的phantomjs.exe文件路径添加到path里面。
2.java 代码
package org.lin.project.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 根据网页地址转换成图片
*/
public class PhantomTools {
private static String BLANK = " ";
// 本地配置(可写在配置文件中,再根据需求注入页面)
private static String tempPath = "D:/work/IDEA/test-server/test/test-web/src/main/webapp/test-admin/assets/testImg";// 图片保存目录
private static String binPath = "D:/1-lin-work/software/phantomjs/bin/phantomjs.exe";// 插件引入地址(phantomjs安装路径)
private static String jsPath = "D:/work/IDEA/test-server/test/test-web/src/main/webapp/test-admin/assets/js/phantomjs.js";// js引入地址
// 执行cmd命令
public static String cmd(String imgagePath, String url) {
return binPath + BLANK + jsPath + BLANK + url + BLANK + imgagePath;
}
//关闭命令
public static void close(Process process, BufferedReader bufferedReader) throws IOException {
if (bufferedReader != null) {
bufferedReader.close();
}
if (process != null) {
process.destroy();
process = null;
}
}
/**
* @param url 网页地址url
* @return 返回生成图片名称
* @throws IOException
*/
public static String printUrlScreen2jpg(String url) throws IOException{
String imgName = System.currentTimeMillis() + ".png";
String imgagePath = tempPath + "/" + imgName;//图片路径
//Java中使用Runtime和Process类运行外部程序
Process process = Runtime.getRuntime().exec(cmd(imgagePath,url));
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String tmp = "";
while ((tmp = reader.readLine()) != null) {
close(process,reader);
}
System.out.println("success");
return imgName;
}
/**
* 测试
*/
public static void main(String[] args) throws IOException {
String url = "https://www.csdn.net/";//网页url
String name = PhantomTools.printUrlScreen2jpg(url);
System.out.println(name);
}
}
3.js 文件
js文件内容如上,这里就不重复贴出来了。
注意:js文件放的位置要对应java程序里面指定的路径!
以上。欢迎各位提出修改建议或意见。