Html转Pdf文档入门汇总

目录

HtmlPdf文档... 1

转化方式说明... 2

PDF文件格式介绍... 2

PDF类型... 2

PDF文件结构可分为以下几块: 4

header 4

body. 4

Cross reference table. 4

trailer: 5

ItextSharp... 5

代码片断如下:... 5

添加引用空间... 5

变量声名: 6

生成bitmap. 6

生成PDF. 6

代码说明... 7

完整的代码... 8

ABCPdf 11

关于ABCpdf 11

使用说明... 11

Hellow World. 12

HTML to PDF代码示例... 12

首先创建Doc对象和设置边框.... 13

添加页并添加网页... 13

把网页全部显示在页面上... 13

让网页上的所有连接有效... 13

保存文档... 13

... 14

完整的HTML转PDF类示例... 14

Pdflib介绍... 15

 

 


转化方式说明

方式一: HTML转成图片,然后把图片添加到PDF文档中.

方式二: 自己解析HTMLCSS,像写HTML哪样添加文本,画表格,画图,添加图片,设置相应的样式等.

方式三: 给一个URL由第三方开发库直接把网页解析,按照网页的样式设置PDF文档样式,相当于方式二不同的是,方式二是自己解析HTMLCSS,自己在PDF文档中画与HTML元素相对应内容; 而方式是完全由第三方开发库完成你只需要给他一个URL.

介绍3个开发库

ItextSharp: HTMLPDF方式有,1,2

ABCpdf: HTMLPDF方式有,1,2,3

其它可用库: Pdflib

PDF文件格式介绍

pdf(Portable   Document   Format,便携式文档结构)是一种很有用的文件格式,其最大的特点是平台无关而且功能强大(支持文字/图象/音乐/视频).先讲一下pdf的文件(物理)结构.

PDF类型

pdf里面8种类型.

Ø  1.booleam

用关键字truefalse表示,可以是array对象的一个元素,dictionary对象的一个条目.

Ø  2.numeric

1.    包括整形和实型,不支持非十进制数字,不支持指数形式的数字.

:
 1)
整数 123 4567 +111 -2     
 
范围:231次方-1到负的231次方
 2)
实数 12.3 0.8 +6.3 -4.01 -3. +.03
 
范围:±3.403 × 1038次方     ±1.175 × 10-38次方
 
注意:如果整数超过表示范围将转化成实数,如果实数超过范围就出错了

Ø  3.string

 由一系列0-255之间的字节组成,一个string总长度不能超过65535.string有以下两种方式:
 1)
()包含起来的一个字串,中间可以使用转义符"/".
 
:
 (abc)  
表示abc
 (a//)  
表示a/
 2)
<>包含起来的一个16进制串,两位表示一个字符,不足两位用补齐
 
:
 <Aabb>  
表示AABB两个字符
 <AAB>  
表示AAB0两个字符

Ø  4.name

 由一个前导/和后面一系列字符组成,最大长度为127.string不同的是,name是不可分割的
 
和唯一的,不可分割就是说一个name对象就是一个原子,比如/name,不能说n就是这个name 一个元素;唯一就是指两个相同的name一定代表同一个对象.pdf1.2开始,除了ascii0,别的都可以用一个#加两个十六进制的数字表示.
 
:
 /name  
表示name
 /name#20is 
表示name is
 /name#200 
表示name 0

/string 表示string

Ø  5.array

 []包含的一组对象,可以是任何pdf对象(包括array).虽然pdf只支持一维array,但可以通过
 array
的嵌套实现任意维数的array(但是一个array的元素不能超过8191)
 
:
 [549 3.14 false (Ralph) /SomeName]

Ø  6.Dictionary

 "<<"">>"包含的若干组条目,每组条目都由keyvalue组成,其中key必须是name对象,并且
 
一个dictionary内的key是唯一的;value可以是任何pdf的合法对象(包括dictionary对象).
 
:
 << /IntegerItem 12
 /StringItem (a string)
 /Subdictionary << /Item1 0.4
 /Item2 true
 /LastItem (not!)
 /VeryLastItem (OK)
 >>
 >>

Ø  7.stream

 由关键字streamendstream包含一系列字节.内容和string很相似,但有区别:stream可以分几次
 
读取,分开使用不同的部分,string必须作为一个整体一次全部读取使用;string有长度限制,
 stream
却没有这个限制.一般较大的数据都用stream表示.

Ø  8.NULL

 null表示,代表空.如果一个key的值为null,则这个key可以被忽略;如果引用一个不存在的
 object
则等价于引用一个空对象.

给大家说点有用的东西:为什么有的pdf不允许打印?
pdf
有自己的加密措施,其中就有限制打印.
找到trailer,如果这个pdf是加密的话会有一个/Encryptname,他的值一般形式是n 0 R,表示这个pdf
文件的加密信息在n 0这个obj里面记录.找到这个obj,其下有一个/Pname,他的值是一个数字(32)其中第三位代表是否有打印权限.

PDF文件结构可分为以下几块:   

header

pdf文件的第一行,格式如下:   
 %PDF-1.3   
表示当前文件的版本是1.3(目前最高版本是多少未知), 软件的版本号总要比文件格式的版本号高1,比如说Read 5能打开的内容就是4

body 

pdf文件中用到的所有对象,包括文本/图象/音乐/视频/字体/超连接/加密信息等等,格式如下:

2   0   obj   
  ...   
  end   obj   
 
其中省略号部分是pdf规定的任意合法对象(一共8)   

例如:

30979 0 obj

<<

/Linearized 1

/O 30982

/H [ 15061 25084 ]

/L 9379963

/E 166967

/N 978

/T 8760262

>>

endobj

第一个数字就是这个OBJ的顺序号,是为了便于在xref中查找,后面的是为了区分不同的OBJ,后面就是关键字obj.下面的各行就是属性,/关键字值 的形式。

Cross reference table

所有pdf对象的引用表,其格式如下
  xref   
  0   5   
  0000000000   65535   f   
  0000000009   00000   n   
  0000000074   00000   n   
  0000000120   00000   n   
  0000000179   00000   n   
 
其中,xref是开始标志,表示以下为引用表内容;0   5表示从对象号为的开始连续有5个对象(0,1,2,3,4),分别用5行来表示.每行的前10个数字代表这个这个对象相对文件头的偏移地址,后面5个数字只有当这个对象被删除的时候才有用,表示这个对象被删除后又被重新生成后的对象号最后一位fn表示对象是否被使用(n表示使用,f表示被删除或没有用)   

trailer:   

位于PDF文件的未尾. 整个pdf文件的入口点,形式如下:   
      trailer   
     <<   
     /Size   8   
     /Root   1   0   R   

/ID [<B29FBB52459C4623DB1A90CBFC28381E><B29FBB52459C4623DB1A90CBFC28381E>]
  >>   
  startxref   
  553   
  %%EOF   

说明:

  /size:  这个pdf中总共使用了多少个对象   
     /root: 
这个pdf文件的catalog对象的对象号,这是pdf中最顶层的对象   
     /startxref:  
后面的数字表示cross   reference   table的开始位置   
     /%%EOF   :
文件结束符.   

/ID 是为了让一些文件检索工具能够唯一区分文件。

ItextSharp

库文件: itextsharp.dll

HTML生成PDF文件有2种方式

第一种: 像写HTML代码哪样, C#往文件流中输出表格,添加文本添加图片等,自己排版.

第二种: 先把HTML生成图片,在向PDF文档中添加图片

这里只介绍第2种方式.

代码片断如下:

添加引用空间

using iTextSharp.text.pdf;

using iTextSharp.text;

using System.Windows.Forms;

using System.IO;

变量声名:

System.Drawing.Bitmap bitmap;

Document document; // ItextShart文档对象,核心对象

string url;

int w, h; // 宽高

生成bitmap

    using (WebBrowser wb = new WebBrowser())

    {

        wb.ScrollBarsEnabled = false;

        wb.Navigate(url); //不支持 file:///F:/m.mht  这种文件地址形URL

        //确保全部解析完毕

        while (wb.ReadyState != WebBrowserReadyState.Complete)

        {

            System.Windows.Forms.Application.DoEvents();

        }

       //获取解析后HTML的大小

        System.Drawing.Rectangle r = wb.Document.Body.ScrollRectangle;

        w = r.Width;

        h = r.Height;

       //设置解析后HTML的可视区域, 说明:这里的可视区域小于HTML页面的实际大小的话会有滚动条,生成的图片也有滚动条; 如果这里的可视大于HTML页面的实际大小,生成的图片下方与右方会有空白

        wb.Width = w;

        wb.Height = h;

        bitmap = new System.Drawing.Bitmap(w, h);

        wb.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, w, h));

    }

生成PDF

     using (MemoryStream ms = new MemoryStream())

      {             

          // 创建PDF的文档对象, PDF文档生成核心对象

           doc = new Document(new Rectangle(0, 0, w, h), 0, 0, 0, 0);//

          // PDF输出流对象

           PdfWriter writer = PdfWriter.GetInstance(doc, ms);            

           writer.CloseStream = false;            

           doc.Open();                         

           iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(bitmap, System.Drawing.Imaging.ImageFormat.Jpeg);            

           img.ScalePercent(100); //图片放缩

          //PDF文档中添加对象

           doc.Add(img);            

           doc.Close(); //

           return ms.ToArray();            

       }

代码说明 

Ø  第一步: 创建一个 iTextSharp.text.Document对象的实例:

Document document = new Document(new Rectangle(0, 0, w, h), 0, 0, 0, 0);

W为宽,H为高.

Document的后边4个参数分别代表左右上下边距.

Rectangle声名如下:

        /// <summary>

        /// Constructs a Rectangle-object.

        /// </summary>

        /// <param name="llx">lower left x</param>

        /// <param name="lly">lower left y</param>

        /// <param name="urx">upper right x</param>

        /// <param name="ury">upper right y</param>

        public Rectangle(float llx, float lly, float urx, float ury);

Document声名如下:

        /// <summary>

        /// Constructs a new Document-object.

        /// </summary>

        /// <param name="pageSize">the pageSize</param>

        /// <param name="marginLeft">the margin on the left</param>

        /// <param name="marginRight">the margin on the right</param>

        /// <param name="marginTop">the margin on the top</param>

        /// <param name="marginBottom">the margin on the bottom</param>

        public Document(Rectangle pageSize, float marginLeft, float marginRight, float marginTop, float marginBottom)

Ø  第二步,创建输出流

可以使用以下任何3,不知道是否还有其它什么可以写入的流

1.  内存流

MemoryStream ms = new MemoryStream();

2.  文件流

FileStream fs =FileStream("Chap0101.pdf", FileMode.Create)

3.  写入流

StreamWriter sw = new StreamWriter("out1.pdf");

Ø  第三步,为该Document创建一个Writer实例

PdfWriter writer = PdfWriter.GetInstance(document, ms);

说明: document为第一步创建的Document实例, ms为第二步创建的输出流.

GetInstance的声名:

        /**

        * Use this method to get an instance of the <CODE>PdfWriter</CODE>.

        *

        * @param    document    The <CODE>Document</CODE> that has to be written

        * @param    os  The <CODE>Stream</CODE> the writer has to write to.

        * @return   a new <CODE>PdfWriter</CODE>

        *

        * @throws   DocumentException on error

        */

       

        public static PdfWriter GetInstance(Document document, Stream os)

 

Ø  第四步,打开当前Document

document.Open();

Ø  第五步,创建图片对像

iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(bitmap, System.Drawing.Imaging.ImageFormat.Jpeg);

Image.GetInstance函数声名:

/// <summary>

/// Converts a .NET image to a Native(PNG, JPG, GIF, WMF) image

        /// </summary>

        /// <param name="image"></param>

        /// <param name="?"></param>

        /// <returns></returns>

        public static Image GetInstance(System.Drawing.Image image, System.Drawing.Imaging.ImageFormat format)

Ø  第六步,Document中添加Image对象

document.Add(img);

Ø  第七步,关闭Document

document.Close();

PDF文档写入trailer, cross reference table(所有pdf对象的引用表)PDF文档的信息

完整的代码

using System;

using iTextSharp.text;

using System.IO;

using System.Threading;

using iTextSharp.text.pdf;

using System.Windows.Forms;

 

namespace MiniItextSharp

{

    class Program

    {

        public class HTML2PDF

        {

            private System.Drawing.Bitmap bitmap;

            private string url;

            private Document doc;

            private int w = 0, h = 0;

            public void SetBitMap()

            {

                using (WebBrowser wb = new WebBrowser())

                {

                    wb.ScrollBarsEnabled = false;

                    wb.Navigate(url); //不支持 file:///F:/m.mht  这种文件地址形URL

                    //确保页面被解析完全

                    while (wb.ReadyState != WebBrowserReadyState.Complete)

                    {

                        System.Windows.Forms.Application.DoEvents();

                    }

                    // 获取HTML的实际大小

                    System.Drawing.Rectangle r = wb.Document.Body.ScrollRectangle;

                    w = r.Width;

                    h = r.Height;

                    // 设置可视区域,太大,会有空白,太小会有滚动条

                    wb.Width = w;

                    wb.Height = h;

                    bitmap = new System.Drawing.Bitmap(w, h);

                    wb.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, w, h));

                    bitmap.Save("t.bmp");

                }

            }

            public byte[] CreatPdf()

            {

               

                try

                {

                    url = "http://localhost/m.mht";

                    Thread thread = new Thread(new ThreadStart(SetBitMap));

                    thread.SetApartmentState(ApartmentState.STA);

                    thread.Start();

                    while (thread.IsAlive)

                        Thread.Sleep(100);

 

                    using (MemoryStream ms = new MemoryStream())

                    {

                        doc = new Document(new Rectangle(0, 0, w, h), 0, 0, 0, 0);// 左右上下

                        PdfWriter writer = PdfWriter.GetInstance(doc, ms);

                        writer.CloseStream = false;

                        doc.Open();

                        iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(bitmap, System.Drawing.Imaging.ImageFormat.Jpeg);

                        img.ScalePercent(100);// 放缩比例

                        doc.Add(img); // 添加对像

                        doc.Close();  //写入PDF文档对象的引用表,trailer

                        return ms.ToArray();

                    }

                }

                catch (Exception err)

                {

                    throw new Exception(err.Message);

                }

            }

        }

 

        static void Main(string[] args)

        {

            HTML2PDF test = new HTML2PDF();

            FileStream file = new FileStream("out.pdf", FileMode.Create);

            byte[] result = test.CreatPdf();

            file.Write(result, 0, result.Length);

            file.Close();

        }

    }

}

ABCPdf

关于ABCpdf

Adobe PDF功能实现是独立的控件。因为它不依赖于任何打印驱动程序,直接生成PDF,所以速度非常之快。

因为它是完全的多线程机制,你可以在ASPX, ASP, VB, C#开发环境和COM+, MTS or .NET 企业服务平台下灵活使用。

它实际上融合了你可能会需要的任何一个功能。然而我们必须注意防止过多地载入对象,以保证使用的简单,优雅和方便。

因为ABCpdf不依赖于任何其他的软件,所以它可以实现完全的多线程,而且不会出现任何令人不悦的瓶颈效果。

ABCpdf.NET是一个能够很方便生成pdf.net组件,能够运行在以下操作系统中:Windows 2000, Windows XP, Windows Server 2003, Windows Vista, and Windows Server 2008.官方建议运行环境安装IE6或者以上版本。对应不同的系统,它有32位和64位的版本,使用时注意版本的选用。

ABCpdf的功能比较 多,比如可以读wordexcel等文件,可以保存pdfxpsswf等格式文件。本文主要介绍其生成pdf的方法。使用时,需要 ABCpdf.DLLABCpdfCE7.DLL支持。其中ABCpdf.DLL.net调用接口)需要引用到项目 中,ABCpdfCE7.DLL(核心驱动)放在ABCpdf.DLL的同一目录下即可。

ABCpdf的坐标系采用Adobe PDF标准坐标系,原点在屏幕的左下角,采用72DPI(我们用的通常是96DPI,在计算大小时注意转换,网页面上的96px相当于ABCpdf里面72px

使用说明

1.       ABCPdf32位于64位版本区分,32位系统下需用32位的ABCpdf,64位的系统下需用64位系统

2.       拷贝….到使用的目录

3.       安装ABCPdf

4.       命名空间

using WebSupergoo.ABCpdf8;
using WebSupergoo.ABCpdf8.Objects;
using WebSupergoo.ABCpdf8.Atoms;
using WebSupergoo.ABCpdf8.Operations;

 

1)  WebSupergoo.ABCpdf8

包含了页面布局的对象,多数时候,仅仅引用这一个空间就足够.

2)  WebSupergoo.ABCpdf8.Objects

包含那些访问和操作你已经添加内容的对象

3)  WebSupergoo.ABCpdf8.Atoms

包含低层访问原生PDF数据结构的对象

4)  WebSupergoo.ABCpdf8.Operations

此命名空间允许你多个参数和回调进行复杂操作

Hellow World

       创建一个PDF文档很简单. 首先创建Document对象,然后向Document对象实例添加内容, 可以是文本,图片,其它类型的图形.

       当在当前页面的内框中添加了所有想添加的内容,可以改变页码添加新的内容.默认是第一页,默认的内框大小为整个页面.

       可以使用FrameRect设置当前页面内框的大小.

       每次向Document对象实例中添加完内容后都会返回该内容对应的ID,可以保存该ID,方便以后对添加的内容进行查询与属性修改.

       示例:

Doc theDoc = new Doc();
theDoc.FontSize = 96;
theDoc.AddText("Hello World");
theDoc.Save(Server.MapPath("simple.pdf"));
theDoc.Clear();

图:


simple.pdf

HTML to PDF代码示例

英文原文: ABCpdf.Net手册中对应目标为:

ABCpdf8>

Examples>

Paged HTML Example

首先创建Doc对象和设置边框.

Doc theDoc = new Doc();
theDoc.Rect.Inset(72, 144);

72: 左边和右边分别与边框的边距为72.

144: 上边和下边分别与边框的边距为144.

添加页并添加网页

theDoc.Page = theDoc.AddPage();// 添加页面
int theID;
theID = theDoc.AddImageUrl("http://www.yahoo.com/"); // 向该页添加网页

把网页全部显示在页面上

while (true) {
theDoc.FrameRect(); // 添加边框
if (!theDoc.Chainable(theID)) // 看看是否还有没有添加完的内容
break; // 没有就结束
theDoc.Page = theDoc.AddPage(); // 如果有就添加新的一页
theID = theDoc.AddImageToChain(theID); // 根据ID添加内容并返回页面上该内容对应的新ID

}

让网页上的所有连接有效

for (int i = 1; i <= theDoc.PageCount; i++) {

theDoc.PageNumber = i;
theDoc.Flatten(); //使超连接有效

}

保存文档

theDoc.Save(Server.MapPath("pagedhtml.pdf")); // 保存文件名为:pagehtml.pdf
theDoc.Clear(); //清理数据

完整的HTML转PDF类示例

   public class AbcPdfBusiness : IPdf

    {

        private Doc pdf = null;

        private string url = null;

 

        public AbcPdfBusiness(string url)

        {

            XSettings.InstallRedistributionLicense("719-253-057");

 

            this.url = url;

           

            pdf = new Doc();

            pdf.MediaBox.String = "0 0 800 900";//页面大小                       

            pdf.Rect.String = "14 20 750 900"; // 内容的所在区间大小

                        

            pdf.HtmlOptions.HideBackground = false; //隐藏网页的背景(不是背景图)

            pdf.HtmlOptions.AddLinks = true; //使HTML链接有效()

 

            pdf.HtmlOptions.AddForms = true;  //是否可使HTMLForm有效.

            pdf.HtmlOptions.AddTags = true;

        }

 

        public byte[] ToBytes()

        {  

            int id = pdf.AddImageUrl(url, true, 1080, true);

           // 分页显示全部内容

            while (true)

            {

                if (!pdf.Chainable(id))

                    break;

                pdf.Page = pdf.AddPage();

                id = pdf.AddImageToChain(id);

            }

 

            pdf.HtmlOptions.LinkPages(); //把网页内部跳转转化为PDF内部跳转

            for (int i = 1; i <= pdf.PageCount; i++)

            {

                pdf.PageNumber = i;

                pdf.Flatten(); //重组和压缩页面的内容可以减少PDF的大小,PDF文档中添加条目返回的ID在此之后无效,: 上边代码id = pdf.AddImageToChain(id);中的ID

            }

 

            MemoryStream stream = new MemoryStream();

            pdf.Save(stream);

            return stream.ToArray();

        }

 

        public void Dispose()

        {

            if (pdf != null)

            {

                pdf.Clear();

                pdf.Dispose();

            }

        }

   

Pdflib介绍

pdflib也提供了一组sdk,但和adobesdk相比,pdflib很小,但功能却一点也不弱。所以对于开发者来说,pdflib是一个明智的选择。你可以从下面的网址得到到它:   
     http://www.pdflib.com/products/pdflib/download/index.html
。如果你没有得到序列号,那么生成的pdf将会加上水印,其他功能和商业版一样。   
    
另外你还可以从下面网址得到pdflib-lite版:   
  http://www.pdflib.com/products/pdflib/download-source.html   
     pdflib-lite
使用协议:   
     http://www.pdflib.com/purchase/license-lite.html   
    
pdflib相比,pdflib-lite最大的特点就是你可以拥有完全的源代码,但功能不如pdflib全面,比如支持的字体要比pdflib少很多。但是,如果你对pdf文件本身很了解的话,你完全可以在pdflib-lite的基础上再做发挥,这就要看你的c语言功底如何了。

下载pdflib压缩包(大约6m)后,在pdflib文件夹下有pdflib.dllpdflib.libpdflib.hpdflib.reg。对于我们来说,只要有前3个文件就可以了。

 

转载于:https://my.oschina.net/qichang/blog/34005

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值