相关专题链接
PDF解决方案(1)--文件上传
PDF解决方案(2)--文件转PDF
PDF解决方案(3)--PDF转SWF
PDF解决方案(4)--在线浏览
前言:最近参与了一个项目,客户要求把系统所有用户提交的所有电子文件(主要是word、Excel、图片等)都转化为PDF格式保存,并且要能支持在线查看、自动加签(添加图片印章、数字证书)等功能,因为之前也没有接触这方面的知识在项目开发过程中也是遇到了诸多困难,但庆幸的是通过自己研究、百度等方法得到了解决,最后的效果还算令人满意,趁现在项目比较空闲把整个实现方案做个介绍。
一、demo效果图
选择文件提交后,在后台先转成pdf文件,然后再转化为swf文件在前台展示! demo比较简陋,没做太多修饰,主要是为了说明问题,大家不要在意这些细节!demo中用到的部分软件在下面下载区有链接,下载解压放在C盘即可。
二、文件上传
1、前台部分
前台采用form表单、隐藏iframe实现无刷新上传:
js部分代码
<script type="text/javascript" src="js/jquery-1.8.0.min.js"></script>
<script type="text/javascript">
//支持的文件上传类型
var accept_extend = ['jpg', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'bmp', 'jpeg', 'png', 'gif'];
var basePath = "<%=basePath%>";
/**
* 校验文件扩展名
* @param {Object} t_ext 文件扩展名
* @return {TypeName} 校验是否通过
*/
function checkFileExtendName(t_ext)
{
var flag = false;
if (t_ext != '')
{
var length = accept_extend.length;
for (var i = 0; i < length; i++)
{
if (t_ext == accept_extend[i]) flag = true;
}
}
return flag;
}
/**
* 文件上传方法
*/
function upload()
{
//校验
var file = document.getElementById("file").value;
if(file == undefined || file == null || file == "" )
{
alert("请选择文件!");
return;
}
var type = file.slice(file.lastIndexOf('.')+1);
if(!checkFileExtendName(type.toLowerCase()))
{
alert("文件类型不支持!");
return;
}
//提交
var form = document.getElementById('upload_form');
form.submit();
//提交按钮控制
$('#uploadBtn').attr('disabled', 'disabled');
$('#loading').css('display', '');
//获取写入隐藏iframe的上传结果
$("#iframe").load(function ()
{
var contents = $(this).contents().get(0);
var data = $(contents).find('body').html();
data = window.eval('(' + data + ')');
if(data.rtncode == 2000)
{
//上传成功后提示并展示swf区域
alert(data.name + "上传成功!");
$("#iframe_pdf_view").width($('body').width() * 0.97).height($('body').height() * 0.85);
$("#iframe_pdf_view").attr("src", basePath + "fileview.jsp?path=" + data.path);
}
$('#uploadBtn').removeAttr('disabled');
$('#loading').css('display', 'none');
$("#iframe").off("load");
});
}
</script>
html部分代码
此处需要注意:文件上传时form表单属性enctype="multipart/form-data"后台才能获取文件流,属性target="iframe"需指向隐藏iframe的name才能实现无刷新上传。
<div style="background-color:#BDD8F2;margin-left:40%;margin-top:20px;border-style:double;margin-right:35%">
<div style="margin-top:10px;margin-left:10px">
<!-- from的target需指向隐藏iframe的name -->
<form id="upload_form" action="commonServlet?type=upload" method="post"
enctype="multipart/form-data" target="iframe" >
<input id="file" type="file" name="file" />
<img id="loading" src="images/loading.gif" style="display:none">
<input id="uploadBtn" type="button" value="提交" onclick="upload()"/>
</form>
<iframe id="iframe" name="iframe" style="width:0px;height:0px"></iframe>
</div>
</div>
<iframe id="iframe_pdf_view" scrolling="auto" frameborder="0" marginheight="0" marginwidth="0"></iframe>
2、后台代码:
后台使用Apache的fileupload包和IO包来解析请求获取文件流:
PrintWriter out = response.getWriter();
// 创建文件处理工厂,它用于生成FileItem对象。
DiskFileItemFactory difactory = new DiskFileItemFactory();
// 设置缓存大小,如果上传文件超过缓存大小,将使用临时目录做为缓存。
difactory.setSizeThreshold(1024 * 1024 * 5);
String dir = this.getServletContext().getRealPath("/");//应用目录
// 设置处理工厂缓存的临时目录,此目录下的文件需要手动删除。
File filedir = new File(dir + "file/temp");
if (!filedir.exists())
{
filedir.mkdirs();
}
difactory.setRepository(filedir);
// 设置文件实际保存的目录
File fudir = new File(dir + "file/upload");
if (!fudir.exists())
{
fudir.mkdirs();
}
//创建request的解析器,它会将数据封装到FileItem对象中。
ServletFileUpload sfu = new ServletFileUpload(difactory);
sfu.setHeaderEncoding("GBK");
//解析保存在request中的数据并返回list集合
List<FileItem> list = null;
try
{
list = sfu.parseRequest(request);
} catch (FileUploadException e)
{
e.printStackTrace();
out.print("{rtncode:2001,message:'" + e.getMessage() + "'}");
out.flush();
out.close();
return;
}
String filename = null;
InputStream in = null;
FileOutputStream fos = null;
if (list != null && list.size() > 0)// 遍历list集合,取出每一个输入项的FileItem对象,并分别获取数据
{
for (Iterator<FileItem> it = list.iterator(); it.hasNext();)
{
FileItem fi = (FileItem) it.next();
if (fi.isFormField())//判断是否为表单属性
{
continue;
}
String originalName = fi.getName();//原始文件名
String extendName = originalName.substring(originalName
.lastIndexOf(".") + 1);//获取原始文件扩展名
filename = UUID.randomUUID().toString() + ".pdf";//新文件名
//获取上传文件流
in = fi.getInputStream();
String pdfPath = dir + "file/upload/" + filename;//生成的PDF路径
fos = new FileOutputStream(pdfPath);//创建文件输出流
//文件转PDF处理
if (Constans.FileExtName.DOC.equalsIgnoreCase(extendName)
|| Constans.FileExtName.DOCX
.equalsIgnoreCase(extendName)
|| Constans.FileExtName.XLS
.equalsIgnoreCase(extendName)
|| Constans.FileExtName.XLSX
.equalsIgnoreCase(extendName))
{
// 调用openoffice转换office文件为PDF并存放到指定目录
PDFUtil.converterOffiec2PDF(in, fos, extendName);
}
else if (Constans.FileExtName.PDF.equalsIgnoreCase(extendName))
{
// 上传pdf文件到指定目录
PDFUtil.uploadPDF(in, fos);
}
else
{
PDFUtil.converterImg2Pdf(in, fos);
}
fi.delete();// 文件删除前需要关闭流
//调用swftools转换PDF为swf文件
if(PDFUtil.convert2SWF(pdfPath))
{
out.print("{rtncode:2000,message:'success',name:'"
+ originalName.substring(0, originalName
.lastIndexOf(".")) + "',path:'"
+ filename.replaceAll(".pdf", ".swf") + "'}");
}
else
{
out.print("{rtncode:2001,message:'error'}");
}
out.flush();
out.close();
}
}
相关文件下载地址
PDF解决方案demo: http://pan.baidu.com/s/1i3mmwux
swftools、xpdf:http://pan.baidu.com/s/1dDu1Yoh(注:解压放在C盘根目录即可)