您的位置:首页 > Web前端 > HTML

Html转Pdf文档入门汇总

2015-01-29 17:07 357 查看
目录

Html转Pdf文档

转化方式说明

PDF文件格式介绍

PDF类型

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

header

body

Crossreferencetable

trailer:

ItextSharp库

代码片断如下:

添加引用空间

变量声名:

生成bitmap

生成PDF

代码说明

完整的代码

ABCPdf

关于ABCpdf

使用说明

HellowWorld

HTMLtoPDF代码示例

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

添加页并添加网页

把网页全部显示在页面上

让网页上的所有连接有效

保存文档



完整的HTML转PDF类示例

Pdflib介绍

转化方式说明

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

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

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

介绍3个开发库

ItextSharp:HTML转PDF方式有,1,2

ABCpdf:HTML转PDF方式有,1,2,3

其它可用库:Pdflib

PDF文件格式介绍

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

PDF类型

pdf里面8种类型.

Ø1.booleam

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

Ø2.numeric

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

例:

1)整数1234567+111-2

范围:正2的31次方-1到负的2的31次方

2)实数12.30.8+6.3-4.01-3.+.03

范围:±3.403×10的38次方
±1.175×10的-38次方

注意:如果整数超过表示范围将转化成实数,如果实数超过范围就出错了

Ø3.string

由一系列0-255之间的字节组成,一个string总长度不能超过65535.string有以下两种方式:

1)由()包含起来的一个字串,中间可以使用转义符"/".

例:

(abc)表示abc

(a//)表示a/

2)由<>包含起来的一个16进制串,两位表示一个字符,不足两位用补齐

例:

<Aabb>表示AA和BB两个字符

<AAB>表示AA和B0两个字符

Ø4.name

由一个前导/和后面一系列字符组成,最大长度为127.和string不同的是,name是不可分割的

和唯一的,不可分割就是说一个name对象就是一个原子,比如/name,不能说n就是这个name的一个元素;唯一就是指两个相同的name一定代表同一个对象.从pdf1.2开始,除了ascii的0,别的都可以用一个#加两个十六进制的数字表示.

例:

/name表示name

/name#20is表示nameis

/name#200表示name0

/string表示string

Ø5.array

用[]包含的一组对象,可以是任何pdf对象(包括array).虽然pdf只支持一维array,但可以通过

array的嵌套实现任意维数的array(但是一个array的元素不能超过8191)

例:

[5493.14false(Ralph)/SomeName]

Ø6.Dictionary

用"<<"和">>"包含的若干组条目,每组条目都由key和value组成,其中key必须是name对象,并且

一个dictionary内的key是唯一的;value可以是任何pdf的合法对象(包括dictionary对象).

例:

<</IntegerItem12

/StringItem(astring)

/Subdictionary<</Item10.4

/Item2true

/LastItem(not!)

/VeryLastItem(OK)

>>

>>

Ø7.stream

由关键字stream和endstream包含一系列字节.内容和string很相似,但有区别:stream可以分几次

读取,分开使用不同的部分,string必须作为一个整体一次全部读取使用;string有长度限制,但

stream却没有这个限制.一般较大的数据都用stream表示.

Ø8.NULL

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

object则等价于引用一个空对象.

给大家说点有用的东西:为什么有的pdf不允许打印?

pdf有自己的加密措施,其中就有限制打印.

找到trailer,如果这个pdf是加密的话会有一个/Encrypt的name,他的值一般形式是n
0R,表示这个pdf

文件的加密信息在n0这个obj里面记录.找到这个obj,其下有一个/P的name,他的值是一个数字(32位)其中第三位代表是否有打印权限.

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

header

pdf文件的第一行,格式如下:

%PDF-1.3

表示当前文件的版本是1.3(目前最高版本是多少未知),
软件的版本号总要比文件格式的版本号高1,比如说Read5能打开的内容就是4。

body

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

20obj

...

endobj

其中省略号部分是pdf规定的任意合法对象(一共8种)

例如:

309790obj

<<

/Linearized1

/O30982

/H[1506125084]

/L9379963

/E166967

/N978

/T8760262

>>

endobj

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

Crossreferencetable

所有pdf对象的引用表,其格式如下xref

05

000000000065535f

000000000900000n

000000007400000n

000000012000000n

000000017900000n

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

trailer:

位于PDF文件的未尾.
整个pdf文件的入口点,形式如下:

trailer

<<

/Size8

/Root10R

/ID[<B29FBB52459C4623DB1A90CBFC28381E><B29FBB52459C4623DB1A90CBFC28381E>]

>>

startxref

553

%%EOF

说明:

/size:这个pdf中总共使用了多少个对象

/root:这个pdf文件的catalog对象的对象号,这是pdf中最顶层的对象

/startxref:后面的数字表示crossreferencetable的开始位置

/%%EOF:文件结束符.,

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

ItextSharp库

库文件:itextsharp.dll

HTML生成PDF文件有2种方式

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

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

这里只介绍第2种方式.

代码片断如下:

添加引用空间

usingiTextSharp.text.pdf;

usingiTextSharp.text;

usingSystem.Windows.Forms;

usingSystem.IO;

变量声名:

System.Drawing.Bitmapbitmap;

Documentdocument;//ItextShart文档对象,核心对象

stringurl;

intw,h;//宽高

生成bitmap

using(WebBrowserwb=
newWebBrowser())

{

wb.ScrollBarsEnabled=false;

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

//确保全部解析完毕

while(wb.ReadyState!=
WebBrowserReadyState.Complete)

{

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

}

//获取解析后HTML的大小

System.Drawing.Rectangler=wb.Document.Body.ScrollRectangle;

w=r.Width;

h=r.Height;

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

wb.Width=w;

wb.Height=h;

bitmap=newSystem.Drawing.Bitmap(w,h);

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

}

生成PDF

using(MemoryStreamms=
newMemoryStream())

{

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

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

//PDF输出流对象

PdfWriterwriter=
PdfWriter.GetInstance(doc,ms);

writer.CloseStream=false;

doc.Open();

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

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

//向PDF文档中添加对象

doc.Add(img);

doc.Close();//

returnms.ToArray();

}

代码说明

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

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

W为宽,H为高.

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

Rectangle声名如下:

///<summary>

///ConstructsaRectangle-object.

///</summary>

///<paramname="llx">lowerleftx</param>

///<paramname="lly">lowerlefty</param>

///<paramname="urx">upperrightx</param>

///<paramname="ury">upperrighty</param>

publicRectangle(floatllx,
floatlly,floaturx,
floatury);

Document声名如下:

///<summary>

///ConstructsanewDocument-object.

///</summary>

///<paramname="pageSize">thepageSize</param>

///<paramname="marginLeft">themarginontheleft</param>

///<paramname="marginRight">themarginontheright</param>

///<paramname="marginTop">themarginonthetop</param>

///<paramname="marginBottom">themarginonthebottom</param>

publicDocument(RectanglepageSize,
floatmarginLeft,floatmarginRight,
floatmarginTop,floatmarginBottom)

Ø第二步,创建输出流

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

1.内存流

MemoryStreamms=
newMemoryStream();

2.文件流

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

3.写入流

StreamWritersw=
newStreamWriter("out1.pdf");

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

PdfWriterwriter=
PdfWriter.GetInstance(document,ms);

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

GetInstance的声名:

/**

*Usethismethodtogetaninstanceofthe
<CODE>PdfWriter</CODE>.

*

*@paramdocumentThe
<CODE>Document</CODE>thathastobewritten

*@paramosThe
<CODE>Stream</CODE>thewriterhastowriteto.

*@returnanew
<CODE>PdfWriter</CODE>

*

*@throwsDocumentExceptiononerror

*/

publicstatic
PdfWriterGetInstance(Documentdocument,
Streamos)

Ø第四步,打开当前Document

document.Open();

Ø第五步,创建图片对像

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

Image.GetInstance函数声名:

///<summary>

///Convertsa.NETimagetoaNative(PNG,JPG,GIF,WMF)image

///</summary>

///<paramname="image"></param>

///<paramname="?"></param>

///<returns></returns>

publicstatic
ImageGetInstance(System.Drawing.Imageimage,System.Drawing.Imaging.ImageFormatformat)

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

document.Add(img);

Ø第七步,关闭Document

document.Close();

向PDF文档写入trailer,crossreferencetable(所有pdf对象的引用表)等PDF文档的信息

完整的代码

usingSystem;

usingiTextSharp.text;

usingSystem.IO;

usingSystem.Threading;

usingiTextSharp.text.pdf;

usingSystem.Windows.Forms;

namespaceMiniItextSharp

{

classProgram

{

publicclass
HTML2PDF

{

privateSystem.Drawing.Bitmapbitmap;

privatestringurl;

private
Documentdoc;

privateintw=0,h=0;

publicvoidSetBitMap()

{

using(WebBrowserwb=
newWebBrowser())

{

wb.ScrollBarsEnabled=false;

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

//确保页面被解析完全

while(wb.ReadyState!=
WebBrowserReadyState.Complete)

{

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

}

//获取HTML的实际大小

System.Drawing.Rectangler=wb.Document.Body.ScrollRectangle;

w=r.Width;

h=r.Height;

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

wb.Width=w;

wb.Height=h;

bitmap=newSystem.Drawing.Bitmap(w,h);

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

bitmap.Save("t.bmp");

}

}

publicbyte[]CreatPdf()

{

try

{

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

Threadthread=
newThread(new
ThreadStart(SetBitMap));

thread.SetApartmentState(ApartmentState.STA);

thread.Start();

while(thread.IsAlive)

Thread.Sleep(100);

using(MemoryStreamms=
newMemoryStream())

{

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

PdfWriterwriter=
PdfWriter.GetInstance(doc,ms);

writer.CloseStream=false;

doc.Open();

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

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

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

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

returnms.ToArray();

}

}

catch(Exceptionerr)

{

throw
newException(err.Message);

}

}

}

staticvoidMain(string[]args)

{

HTML2PDFtest=
newHTML2PDF();

FileStreamfile=
newFileStream("out.pdf",
FileMode.Create);

byte[]result=test.CreatPdf();

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

file.Close();

}

}

}

ABCPdf

关于ABCpdf

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

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

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

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

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

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

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

使用说明

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

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

3.安装ABCPdf

4.命名空间

usingWebSupergoo.ABCpdf8;


usingWebSupergoo.ABCpdf8.Objects;


usingWebSupergoo.ABCpdf8.Atoms;


usingWebSupergoo.ABCpdf8.Operations;




1)
WebSupergoo.ABCpdf8


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


2)
WebSupergoo.ABCpdf8.Objects


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


3)
WebSupergoo.ABCpdf8.Atoms


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


4)
WebSupergoo.ABCpdf8.Operations


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


HellowWorld

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

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

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

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

示例:

DoctheDoc=newDoc();


theDoc.FontSize=96;


theDoc.AddText("HelloWorld");


theDoc.Save(Server.MapPath("simple.pdf"));


theDoc.Clear();


图:


simple.pdf

HTMLtoPDF代码示例

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

ABCpdf8>

Examples>

PagedHTMLExample

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

DoctheDoc=newDoc();


theDoc.Rect.Inset(72,144);


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


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


添加页并添加网页

theDoc.Page=theDoc.AddPage();//
添加页面


inttheID;


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(inti=1;i<=theDoc.PageCount;i++){


theDoc.PageNumber=i;


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


}


保存文档

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


theDoc.Clear();//
清理数据


完整的HTML转PDF类示例

publicclass
AbcPdfBusiness:IPdf

{

privateDocpdf=
null;

privatestringurl=
null;

publicAbcPdfBusiness(stringurl)

{

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

this.url=url;

pdf=new
Doc();

pdf.MediaBox.String="00800900";//页面大小

pdf.Rect.String="1420750900";//内容的所在区间大小

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

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

pdf.HtmlOptions.AddForms=true;//是否可使HTML的Form有效.

pdf.HtmlOptions.AddTags=true;

}

publicbyte[]ToBytes()

{

intid=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(inti=1;i<=pdf.PageCount;i++)

{

pdf.PageNumber=i;

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

}

MemoryStreamstream=
newMemoryStream();

pdf.Save(stream);

returnstream.ToArray();

}

publicvoidDispose()

{

if(pdf!=
null)

{

pdf.Clear();

pdf.Dispose();

}

}

Pdflib介绍

pdflib也提供了一组sdk,但和adobe的sdk相比,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.dll,pdflib.lib,pdflib.h,pdflib.reg。对于我们来说,只要有前3个文件就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐