ABCpdf.net的使用介绍

最新做一个项目需要生成pdf文档以供打印,研究决定使用abcpdf这款组件,先针对其使用方法做一个简单的总结介绍以给有需要的朋友做参考。


一、 ABCpdf.NET简单介绍
ABCpdf.NET是一个能够很方便生成pdf的.net组件,能够运行在以下操作系统中:Windows 2000, Windows XP, Windows Server 2003, Windows Vista, and Windows Server 2008.官方建议运行环境安装IE6或者以上版本。对应不同的系统,它有32位和64位的版本,使用时注意版本的选用。
ABCpdf的功能比较多,比如可以读word、excel等文件,可以保存pdf、xps、swf等格式文件。本文主要介绍其生成pdf的方法。使用时,需要ABCpdf.DLL和ABCpdfCE7.DLL支持。其中ABCpdf.DLL(.net调用接口)需要引用到项目中,ABCpdfCE7.DLL(核心驱动)放在ABCpdf.DLL的同一目录下即可。
ABCpdf的坐标系采用Adobe PDF标准坐标系,原点在屏幕的左下角,采用72DPI(我们用的通常是96DPI,在计算大小时注意转换,网页面上的96px相当于ABCpdf里面72px)

二、 入门,生成第一个pdf文件
这一节将通过实例来展示如何用ABCpdf.NET生成pdf文件。在使用前需要引入ABCpdf.DLL,在代码中引用名空间:using WebSupergoo.ABCpdf7;通常情况下只需要引入这个名空间就可以了。
Code:
    private void GeneratePdfTest1()
    {
         using (Doc theDoc = new Doc())
            {
                theDoc.Rect.Inset(24, 48);
                //Rect默认是文档整个页面大小, 这里的Inset表示将Rect左右留出24的空白,上下留出48的空白
               
                theDoc.Color.String = "32,48,117";
                theDoc.FrameRect();//为当前rect添加边框
                theDoc.MediaBox.String = "0 0 590 840";//设置添加新页面时,页面的大小
                theDoc.Rect.String = "14 14 576 770";//当前输出区间
                theDoc.Color.String = "192,48,117";
                theDoc.FrameRect();
                theDoc.FontSize = 12;
                theDoc.AddText("Hello World");
                theDoc.Font = theDoc.AddFont("宋体", "ChineseS");
                theDoc.FontSize = 16;
                theDoc.Flatten();//合并pdf各个layer,减少pdf大小
                theDoc.Save(Server.MapPath("simple.pdf"));
                theDoc.Clear();
            }
        }
上面的代码可以简单的生成一个pdf文件。

三、 进阶,控制生成的pdf
上面的代码只是简单的生成了一个pdf,很多细节问题都没有说明,现在将介绍如何控制生成的pdf和介绍一些有用的方法。比如页面的大小、字体、添加的内容位置等。
WebSupergoo.ABCpdf7.Doc类有很多属性和方法可以利用,这里我们就要用到:

1. SetInfo方法
virtual void SetInfo(int id, string type, string value)
用来获取或者改变pdf页面各对象的外观情况,id通过getinfo方法可以获取。
e.g.默认的pdf页面大小是a4页面大小,可以用这个方法来改变当前页面的大小。
theDoc.SetInfo(theDoc.Page, "/MediaBox:Rect", "0 0 200 300");

2. Rect属性
这是一个很重要的属性,abcpdf里面生成pdf的基本思路就是先确定一个rect再向该rect里里面添加内容,所有的pdf对象都依赖rect,用rect来定位的。
e.g.在指定位置添加文字。
theDoc.Rect.String = "14 14 576 770";
theDoc.AddText("Hello World");
当然,可以在添加文字前设置字体和颜色等信息:
theDoc.Font = theDoc.AddFont("宋体", "ChineseS");
theDoc.FontSize = 12;
theDoc.Color.String = "192,48,117";

3. MediaBox属性
设置MediaBox属性只会影响后面添加的页面大小,后面添加的页面大小将会是MediaBox设置的大小。它不会影响已存在的页面大小。改变已存在页面大小用setinfo方法。

4. Layer属性
获取或设置当前层,和html的层是一样的,前面的层会覆盖后面的层。默认的Layer为1,在最前面。

AddHtml添加html代码(将会被解析,但此方法不支持css)支持以下html标记:
<Head>
<Body>
<BR>
<P>
<H1> to <H6>
<List>
<UL>
<OL>
<LI>
<A>
<B>
<I>
<U>
<Strike>
<Sup>
<Sub>
<Font>
<StyleRun>
<BlockQuote>
<Pre>
e.g.Code:
Doc theDoc = new Doc();
theDoc.FontSize = 72;
theDoc.AddHtml("<b>Gallia</b> est omnis divisa in partes tres, quarum unam incolunt <b>Belgae</b>, aliam <b>Aquitani</b>, tertiam qui ipsorum lingua <b>Celtae</b>, nostra <b>Galli</b> appellantur.");
theDoc.Save(Server.MapPath("docaddhtml.pdf"));
theDoc.Clear();

5. AddImageHtml方法
virtual int AddImageHtml(string html)
virtual int AddImageHtml(string html, bool paged, int width, bool disableCache)
html 需要添加的html
paged 是否分页,true启用分页
width 页面的宽度(浏览器解析html时浏览器的宽度)
disableCache 是否忽略缓存,true不启用缓存,false启用缓存,缓存时间5分钟
return 返回添加的html对象id
说明:这个方法和AddImageUrl基本上是一样的,只不过这个直接用的html,AddImageUrl用的是url地址。这个方法将用传入的html生成一个临时文件,然后解析该临时文件来为pdf添加相关内容。这个是一个很简单的方法,它不提供任何性能上的提升。如果是在asp.net中使用,需要IIS拥有对临时文件夹的完全访问权限,否则将会出现错误。如果html内含有外部的样式和图片,则需要用绝对地址,因为传入的html没有具体的地址,将会无法解析其包含的相对地址。如果必须用相对地址,请用AddImageUrl方法。
e.g.Code:
Doc theDoc = new Doc();
using (StreamReader sReader = new StreamReader(Server.MapPath("s.html")))
{
theDoc.AddImageHtml(sReader.ReadToEnd(),true,760,true);
}

6. AddImageUrl方法
virtual int AddImageUrl(string url)
virtual int AddImageUrl(string url, bool paged, int width, bool disableCache)
参数说明同上,只不过是将html换成了url。
说明:通过这个方法可以很方便的将一个web page添加到pdf文件,其解析web page用的是ie的内核(版本估计和机器上安装的版本相关,有兴趣可以利用css测试一下)。值得注意的一个问题是pdf的dpi是72,通常html的dpi是96,所以如果要pdf上显示的和浏览器上看到的一样大,那么在设置rect大小(会填满所设置的rect)的时候需要用width参数乘以72/96。
e.g.Code:
Doc theDoc = new Doc();
theDoc.AddImageUrl("http://www.google.com/");
theDoc.Save(Server.MapPath("htmlimport.pdf"));
theDoc.Clear();

四、 进阶,如何分页
在利用html转pdf的时候,通常都会遇到的问题。abcpdf会进行智能的分页,而分页的实现也只需要几行代码。
int theID = theDoc.AddImageUrl("http://localhost:1141/WebSitePDF/000001.OF.html", true, 760, true);
//以下实现多页效果
while (true)
{
     theDoc.FrameRect();//画Rect的边框
     if (!theDoc.Chainable(theID))
        break;
     theDoc.Page = theDoc.AddPage();
     theID = theDoc.AddImageToChain(theID);
}
如果需要在分页时不对模块进行截断,请为相应模块添加打印样式“page-break-inside: avoid”如果需要在指定位置进行强制分页,请添加:“<div style="page-break-before:always">&nbsp;</div>”其中“&nbsp;”是必须要的。经过我的实验此强制分页标记并不是任何时候都分页的,用之前注意针对指定的html代码进行测试。推荐用自动分页+保证模块完整性样式。
对于需要设置页眉和页脚的,也很简便,只要将页面分成三个rect(页眉,页脚,中间内容),分页的时候将内容添加到中间的rect,分页完毕后再分别补充页面,页脚。
e.g.Code:
theDoc.Rect.String = "14 35 576 803";
int theID = theDoc.AddImageUrl(url, true, 760, true);
//以下实现多页效果
while (true)
{
if (!theDoc.Chainable(theID))
   break;
theDoc.Page = theDoc.AddPage();
theID = theDoc.AddImageToChain(theID);
}

for (int i = 1; i <= theDoc.PageCount; i++)
{
theDoc.PageNumber = i;
表头
theDoc.Rect.String = "14 803 576 835";
theDoc.AddImageUrl(urlTop, false, 760, true);
表尾
theDoc.Rect.String = "14 35 576 5";
theDoc.AddImageUrl(urlBottom, false, 760, true);
}

五、 运行js,js支持
abcpdf支持html页面脚本JavaScript,这让我们利用html生成pdf时多了一个利器,可以通过js改变html,再生成pdf。如何执行页面上的js呢?下面将介绍几个相关的属性。注意这个受运行机器浏览器安全设置限制,如果浏览器安全级别很高或者限制了js的运行,在调用js的时候将会报错:Unable to apply JScript
Windows error 5. Access is denied.

1. theDoc.HtmlOptions.UseScript
是否启用脚本,默认为false不启用

2. theDoc.HtmlOptions.OnLoadScript
当启用脚本时,页面载入后执行的脚本,可以是一段js代码,也可以是html页面包含函数方法

3. theDoc.HtmlOptions.HostWebBrowser
是否启用WebBrowser,默认为false不启用。只有在启用了WebBrowser后,left, top, width, height, offsetLeft, offsetTop, offsetWidth, offsetHeight, clientLeft, clientTop, clientWidth, clientHeight, pixelLeft, pixelTop, pixelWidth, pixelHeight, posLeft, posTop, posWidth, and posHeight这些dom方法才可用,否则都是0。在启用WebBrowser后,还可以用用xml,xslt。

e.g.Code:
theDoc.HtmlOptions.UseScript = true;
theDoc.HtmlOptions.HostWebBrowser = true;
theDoc.HtmlOptions.OnLoadScript ="var divs=document.getElementById('content').childNodes;if(divs[0].scrollHeight<divs[1].scrollHeight)divs[0].style.height=divs[1].scrollHeight;";

六、 关于程序发布注册
对于发布程序,需要在创建doc对象前注册一些该组件的key,如下:
XSettings.InstallRedistributionLicense(" 注册码");
Doc doc = new Doc();
Response.Write("License: " + doc.License + "<br>");
或者
Doc theDoc = new Doc();
// here we use a trial license key as copied from the PDFSettings application
theDoc.SetInfo(0, "License", "cd9b5c07db69df2bf57c0a04d9bca58b10c44889c9fb197984e592f49addfce5ec5fe85d7b9205bc");
Response.Write(theDoc.GetInfo(0, "License"));
在程序引入的dll版本要和打包的版本一致,否则会出现找不到xx版本dll的错误,编译时将dll的版本号也包含进去了,大概是因为该dll是强命名的原因。

posted @ 2010-01-21 00:07 李楠友 阅读(386) | 评论(1) | 编辑

PDF屏蔽打印,隐藏工具栏和菜单栏

PDF屏蔽打印,隐藏工具栏和菜单栏

刚研究了一下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里面设置缓存存在时间。代码太长了我就不贴原文了,贴一下地址大家可以去下载。
中文版:http://www.javaresearch.org/article/17251.htm
英文版:http://www.onjava.com/pub/a/onjava/2003/06/18/dynamic_files.html
英文版有源码下载


下面贴一个用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");
     }
}


posted @ 2010-01-21 00:04 李楠友 阅读(264) | 评论(0) | 编辑

2010年1月20日 #

pdf

在IE中显示pdf文档的方法及参数设置

这是在为学院做精品课程网站的时候遇到的一个问题,老师提供的资料都是pdf格式的,如果访问者的计算机上没有装acrobat reader,直接用iframe或者直接用链接打开,那就不是打开文档,而是直接下载了,为了防止下载,想像到媒体文件的播放方式,加上一些官方的docs,考虑用用object标签使用pdf插件嵌入ie中,结果可行。
代码如下:
<DIV id=showdiv
style=”Z-INDEX: 0; LEFT:10px; WIDTH: 10px; POSITION: absolute; TOP: -30px; HEIGHT: 10px”>
<object classid=”clsid:CA8A9780-280D-11CF-A24D-444553540000″ width=”1000″ height=”700″ border=”0″  top=”-10″  name=”pdf”>
<param name=”toolbar” value=”false”>
<param name=”_Version” value=”65539″>

<param name=”_ExtentX” value=”20108″>

<param name=”_ExtentY” value=”10866″>

<param name=”_StockProps” value=”0″>

<param name=”SRC” value=”name.pdf”>
</object>
</DIV>
这样防止了没有安装阅读器的访问者下载文件,然而,在没有安装acrobat reader的情况下,网页显示一片空白,没有任何提示用户安装的阅读器的信息,这对做网页设计的人来说是个大忌,又想到用activeX的方式,结果以失败告终,最后只好采用javascript的方式,用try{..}catch{..}的方式来捕获创建activeX对象中产生的异常,这种方式只能验证单个版本的acrobat reader ,也被淘汰,用google搜索了下E文站点,发现这个问题在国外的一些论坛上很多,而且解决方法也很多,经过测试,最终决定采用的代码如下:
<HTML>
    <HEAD>
        <META http-equiv="Content-Type" content="text/html; charset=gb2312">
        <META http-equiv="Content-Style-Type"  content="text/css">
        <META http-equiv="Content-Script-Type" content="text/javascript">
        <TITLE>Checking if Acrobat Reader installed (IE4+)...</TITLE>
        <SCRIPT for="window" event="onload"
<!--
            document.all [
                         document.all.PDFNotKnown ? "IfNoAcrobat" : "IfAcrobat"
                         ] .style.display = "block";
        //--></SCRIPT>
    </HEAD>
    <BODY>
        <NOSCRIPT>
            Cannot determine if you have Acrobat Reader (or the full Acrobat)
            installed <FONT size="-1">(because JavaScript is unavailable or
            turned off)</FONT>.
        </NOSCRIPT>
        <DIV id="IfNoAcrobat" style="display:none">
            你需要先安装Adobe Reader才能正常浏览文件,请点击这里下载Adobe Reader.
        </DIV>
        <OBJECT type="application/pdf" width=0 height=0 style="display:none">
            <DIV id="PDFNotKnown" style="display:none"> </DIV>
        </OBJECT>
</BODY>
</HTML>

 

转载自:

  http://www.cnblogs.com/pentiunz/archive/2010/11/11/1874502.html

ABCpdf.Net下载地址:

 http://abcpdf-net.updatestar.com/licenses

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值