项目需求是将网页上的账单下载成pdf格式的,网上找了一下前辈用的工具,最后选择使用wkhtmltopdf。将自己写的代码简单的做个整理吧。
1、首先从前端传来需要转换的文件(我这边是在前端直接抓取了需要转换的网页内容,传给后台一个String进行处理)
/**
* 将传入的源文件或者网络路径生成pdf
* @param data 需要生成pdf的源文件或者网络路径
*/
@RequestMapping(value="getPdf",method= RequestMethod.POST)
@ResponseBody
public ResultJson getPdf(HttpServletRequest request,HttpServletResponse response,String data){
ResultJson resultJson = new ResultJson();
SimpleDateFormat sdf = new SimpleDateFormat( "yyyyMMddHHmmss" );
//生成的文件为年月日+时分秒+4位随机数(1970-1-1到现在的毫秒数取余10000)
String name = sdf.format(new Date())+currentTimeMillis()%10000;
String destPathHtml =request.getSession().getServletContext().getRealPath("/")+"download/"+name+".html";
String destPathPdf =request.getSession().getServletContext().getRealPath("/")+"download/"+name+".pdf";
//将字符串写入到HTML文件中
StringToHtml.stringToHtml(data,destPathHtml);
//将HTML文件转换为PDF文件
boolean isSuccess = Htmltopdf.convert(destPathHtml,destPathPdf);
//下载文件
DownloadPdf.download(destPathPdf,response);
//删除html文件
delFile(destPathHtml);
if(isSuccess){
ControllerUtil.setSuccessJson(resultJson,isSuccess);
return resultJson;
}else{
return resultJson;
}
}
public static void delFile(String file){
File f = new File(file);
if(f.exists() && f.isFile()){
f.delete();
}
}
2、将字符串写入到HTML文件中
/**
* @author djg
* 将传入的字符串写入到html文件中
*/
public class StringToHtml {
public static void stringToHtml(String s,String path){
if(s != null){
try {
File file = new File(path);
if(!file.exists()){
File dir = new File(file.getParent());
dir.mkdirs();
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fileOutputStream,"utf-8");
osw.write(s);
osw.flush();
osw.close();
fileOutputStream.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
3、将HTML文件转换为PDF文件
public class Htmltopdf {
/**
*wkhtmltopdf在硬盘的安装路径
*/
//我这里是使用配置文件读取的
private static final String WK_HTML_TO_PDF = Global.getResource("wkhtmltopdf");
public static boolean convert(Object srcPath,String destPath){
File file = new File(destPath);
File parent = file.getParentFile();
if(!parent.exists()){
parent.mkdirs();
}
StringBuilder cmd = new StringBuilder();
// cmd.append("C:/wkhtmltopdf/bin/wkhtmltopdf");
cmd.append(WK_HTML_TO_PDF);
cmd.append(" ");
cmd.append("--page-size A4");
cmd.append(" ");
cmd.append(srcPath);
cmd.append(" ");
cmd.append(destPath);
boolean result = true;
try {
Process process = Runtime.getRuntime().exec(cmd.toString());
HtmlToPdfInter error = new HtmlToPdfInter(process.getErrorStream());
HtmlToPdfInter output = new HtmlToPdfInter(process.getInputStream());
error.start();
output.start();
process.waitFor();
}catch (Exception e){
result = false;
}
return result;
}
// public static void main(String[] args){
// String htmlUrl = "www.baidu.com";
// String path = "f:\\pdf_test.pdf";
// convert(htmlUrl , path );
// }
}
public class HtmlToPdfInter extends Thread{
private static final Logger LOG = LoggerFactory
.getLogger(HtmlToPdfInter.class);
private InputStream is;
public HtmlToPdfInter(InputStream is) {
this.is = is;
}
@Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
br.readLine();
} catch (IOException e) {
LOG.error(e.getMessage());
e.printStackTrace();
}
}
}
4、下载文件
**
* @author djg
* 下载pdf文件
*/
public class DownloadPdf {
/**
* 下载
* @param path 需要下载的文件的路径
* @param response
*/
public static void download(String path, HttpServletResponse response){
try{
File file = new File(path);
String fileName = file.getName();
String ext = fileName.substring(fileName.lastIndexOf(".")+1).toUpperCase();
//以流的形式下载文件
InputStream is = new BufferedInputStream(new FileInputStream(file));
byte[] bytes = new byte[is.available()];
is.read(bytes);
is.close();
//清空response
response.reset();
//设置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" +new String(fileName.getBytes()));
response.addHeader("Content-Length", "" + file.length());
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
toClient.write(bytes);
toClient.flush();
toClient.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
码代码时间不长,哪里有问题希望看的兄弟指正。