刚研究了一下PDF文件现在把研究成果写在下面。
用户的需求都是这么BT:
1.
用网页打开 PDF文件。
2.
只可以浏览但是不许打印保存。
仔细分析之后发现之前见过这样的PDF档没有工具栏,打印的按钮灰掉。
但是如果用IE打开文件也会在IE的临时文件夹里面找到。只有做到清缓存。
PDF的文件用IE打开的时候自己有工具栏。真是要死了,在网上搜了很久如何屏蔽打印和保存,搜到的都是如何破解。考虑了两个开源保PDFBox和iText。想要用PdfBox实现屏蔽打印但是在官网上面找到的例子都是着重在数据抽取上的,觉得他的实现其实做得不好(可能是对他不够了解)在它身上花了2天时间之后转去考虑iText.
Itext官网上面的实例很全面而且实现起来也很简单。下面是实现代码:
import
java.io.FileOutputStream;
import
com.lowagie.text.Document;
import
com.lowagie.text.Font;
import
com.lowagie.text.PageSize;
import
com.lowagie.text.Paragraph;
import
com.lowagie.text.Rectangle;
import
com.lowagie.text.pdf.PdfContentByte;
import
com.lowagie.text.pdf.PdfCopy;
import
com.lowagie.text.pdf.PdfEncryptor;
import
com.lowagie.text.pdf.PdfImportedPage;
import
com.lowagie.text.pdf.PdfReader;
import
com.lowagie.text.pdf.PdfWriter;
publicclass
PdfHandle {
publicvoid
hideBars(String inputFile,String outFile)
{
//
复制一个
PDF
try
{
//
创建一个
reader
PdfReader reader =
new
PdfReader(inputFile);
int
n = reader.getNumberOfPages();
//
得到第一页
Rectangle psize = reader.getPageSize(1);
float
width = psize.height();
float
height = psize.width();
// step 1:
创建一个
document
对象
Document document =
new
Document(
new
Rectangle(width, height));
// step 2:
创建一个
write
PdfCopy writer =
new
PdfCopy(document,
new
FileOutputStream(outFile));
//
设置隐藏菜单栏和工具栏
writer.setViewerPreferences(PdfWriter.
HideMenubar
| PdfWriter.
HideToolbar
);
// step 3:
打开
document
document.open();
// step 4:
一页一页添加内容
int
i = 0;
while
(i < n) {
document.newPage();
i++;
PdfImportedPage page1 = writer.getImportedPage(reader, i);
writer.addPage(page1);
}
// step 5:
关闭
document
document.close();
}
catch
(Exception de) {
de.printStackTrace();
}
}
publicvoid
notAllowPrint(String inputFile,String outFile)
{
try
{
PdfReader reader =
new
PdfReader(inputFile);
//
设置加密权限
PdfEncryptor.encrypt(reader,
new
FileOutputStream(outFile),
null
,
null
,
PdfWriter.
AllowAssembly
|PdfWriter.
AllowFillIn
|PdfWriter.
AllowScreenReaders
,
false
);
}
catch
(Exception e) {
e.printStackTrace();
}
}
publicstaticvoid
main(String args[])
{
PdfHandle pp=
new
PdfHandle();
pp.hideBars(
"e://3.pdf"
,
"e://4.pdf"
);
pp.notAllowPrint(
"e://4.pdf"
,
"e://5.pdf"
);
}
}
以上程序测试过没有问题。使用时要加入itext.jar到工程里面。
方法1.去掉工具栏。这个很简单。
方法2.屏蔽打印,这个方法其实屏蔽了很多权限,可以在文档中查到。
Encrypt
方法的第
5
个参数是受权参数,如果希望用户有什么权限则在这里面定义。如果第三个第四个参数里面定义了密码则用户打开文档就必须输入密码,如果授权为允许打印有定义了密码则不会达到我们单纯屏蔽打印按钮的目的。
权限由如下几种:
AllowPrinting
AllowModifyContents
AllowCopy
AllowModifyAnnotations
AllowFillIn
AllowScreenReaders
AllowAssembly
AllowDegradedPrinting
有兴趣的话大家可以反复试验一下授权,密码之类的。
最后说一下ie缓存的问题。我搜到了一篇关于用servlet输出PDF文件的实例,可以在sevlet里面设置缓存存在时间。代码太长了我就不贴了贴一下地址大家可以去下载。
自英文版有源码下载
下面贴一个用PDFBox解决这个问题的代码,但是这个是需要安全证书的因为没有所以最终放弃了这个方案。供大家参考。
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.InputStream;
import
java.security.cert.CertificateFactory;
import
java.security.cert.X509Certificate;
import
junit.framework.Assert;
import
org.pdfbox.pdmodel.PDDocument;
import
org.pdfbox.pdmodel.encryption.AccessPermission;
import
org.pdfbox.pdmodel.encryption.PublicKeyProtectionPolicy;
import
org.pdfbox.pdmodel.encryption.PublicKeyRecipient;
publicclass
HandlePDF {
publicvoid
setFileProperty(String inputname,String outputname,String certi)
{
File publicCert1;
File input;
File output;
AccessPermission accessPermission =
new
AccessPermission();
accessPermission.setCanAssembleDocument(
false
);
accessPermission.setCanExtractContent(
false
);
accessPermission.setCanExtractForAccessibility(
true
);
accessPermission.setCanFillInForm(
false
);
accessPermission.setCanModify(
false
);
accessPermission.setCanModifyAnnotations(
false
);
accessPermission.setCanPrint(
false
);
accessPermission.setCanPrintDegraded(
false
);
publicCert1 =
new
File(certi);
input =
new
File(inputname);
output =
new
File(outputname);
try
{
PDDocument doc = PDDocument.load(input);
protect(doc, publicCert1.getAbsolutePath(),accessPermission);
doc.save(output.getAbsolutePath());
doc.close();
}
catch
(Exception e)
{
e.printStackTrace();
}
}
privatevoid
protect(PDDocument doc, String certPath,AccessPermission accessPermission)
throws
Exception
{
InputStream inStream =
new
FileInputStream(certPath);
CertificateFactory cf = CertificateFactory.getInstance(
"X.509"
);
Assert.assertNotNull(cf);
X509Certificate certificate = (X509Certificate)cf.generateCertificate(inStream);
Assert.assertNotNull(certificate);
inStream.close();
PublicKeyProtectionPolicy ppp =
new
PublicKeyProtectionPolicy();
PublicKeyRecipient recip =
new
PublicKeyRecipient();
recip.setPermission(accessPermission);
recip.setX509(certificate);
ppp.addRecipient(recip);
doc.protect(ppp);
}
publicstaticvoid
main(String[] args)
{
HandlePDF hpdf=
new
HandlePDF();
hpdf.setFileProperty(
"f://3.pdf"
,
"f://4.pdf"
,
"f://c.der"
);
}
}
程序进过测试会报证书文件错误。
itext官网:http://www.lowagie.com/iText/
PdfBox官网:http://www.pdfbox.org/
原文转载自: http://blog.csdn.net/l0979365428/article/details/1786380