PdfSharp 使用,创建PDF文档

前言关于 PdfSharp下载 PdfSharp使用PdfSharp常用命名空间和类1 创建一个简单的PDF文档2 创建一个带页脚的PDF文档2.1 创建临时数据表2.2 创建页脚2.3 完整代码

小结附录:

往期文章:

1、

c# 数据保存为PDF(一) (Spire.PDF篇)

2、c# 数据保存为PDF(二) (Apose.Pdf篇)

前言

因为项目需求需要将数据导出存为PDF文档,方便客户使用。相比于TXT ,EXCEL等格式,导出PDF时可以减少字体乱码,文体格式不一样的痛点。在前面试用了Spire.PDF和Aspose.Pdf都可以导出我想要的格式的PDF,但这两个没有开源,正版都是要收费的,只好另寻他欢罢了。之后,寻寻觅觅,终于遇见PdfSharp,相处一段时间后,那便是日久生情了,陷进去了,从此就是它啦。

关于 PdfSharp

PdfSharp是一个开源免费的.NET开发包,可以生成PDF格式的文档。对于第三个特点真的特好使,深有体会,后面会有一篇博文介绍的。 PdfSharp组件主要特点有:

1.全部用C#重写设计和编写代码; 2.很容易使用对象模型来构建文档; 3. 可以生成PDF文件和显示在窗体或者打印,都使用同一个源文件; 4.可以修改、合并或者分割PDF文件; 5. 可以控制图片的透明度,嵌入字体。

下载 PdfSharp

通过VS自带的Nuget包管理器直接搜索PdfSharp并下载。路径在工具-----Nuget包管理器-----管理解决方案的NuGet程序包…

使用PdfSharp

常用命名空间和类

命名空间

using PdfSharp;

using PdfSharp.Drawing;

using PdfSharp.Pdf;

常用类库

类库描述PdfSharp.Pdf.PdfDocumentPDF文档PdfSharp.Pdf.PdfPagePDF 页面PdfSharp.Drawing.XGraphics画布PdfSharp.Drawing.XBrushes画刷PdfSharp.Drawing.XPen画笔PdfSharp.Drawing.XFont字体PdfSharp.Drawing.XStringFormat字符串格式PdfSharp.Drawing.XSize大小

1 创建一个简单的PDF文档

创建一个简单的HelloWorld.pdf文档。

///

/// PdfSharp 创建一个简单的PDF

///

public static void CreateSinglePdf()

{

// 创建一个PDF文档对象

PdfDocument document = new PdfDocument();

document.Info.Title = "Created with PDFsharp";

// 创建一个空的Page

PdfPage page = document.AddPage();

// 创建一个画布对象,用于绘制

XGraphics gfx = XGraphics.FromPdfPage(page);

// 创建字体

XFont font = new XFont("Verdana", 20, XFontStyle.BoldItalic);

// 绘制文本

gfx.DrawString("Hello, World!", font, XBrushes.Black,

new XRect(0, 0, page.Width, page.Height),

XStringFormats.Center);

// 保存文档

const string filename = "HelloWorld.pdf";

document.Save(filename);

}

2 创建一个带页脚的PDF文档

类似下图的模板:列数可以减少 分析需求: 1 有项目的头部介绍信息。 2 有页脚,页脚信息包括公司信息和页码。 3 表格内容有标题,换页到下页时标题也要有。 4 KK00 KK11 KK22等加粗有下划线,凸显出分类隔开的特点。

2.1 创建临时数据表

创建100*5的数据存放在DataTable中,仅用作测试。实际项目中,可以换成需要保存的数据内容。

///

/// 数据表格

///

///

private static DataTable CreateData()

{

DataTable dt = new DataTable();

DataColumn col1 = new DataColumn("Num", typeof(string));

DataColumn col2 = new DataColumn("Name", typeof(string));

DataColumn col3 = new DataColumn("Val", typeof(string));

DataColumn col4 = new DataColumn("Des", typeof(string));

DataColumn col5 = new DataColumn("Set", typeof(string));

dt.Columns.Add(col1);

dt.Columns.Add(col2);

dt.Columns.Add(col3);

dt.Columns.Add(col4);

dt.Columns.Add(col5);

Random random = new Random();

List nameList = new List

{

"A", "BB", "CCC", "D",

"E", "F", "G","H","II",

"JJ", "LL", "M"

};

List tempList = new List

{

"dsd", "sdfdgvre", "Hello", "Gilrs",

"Today", "YYYY", "dfgre","GSD","fdgfer",

"Wesd", "DLG", "fsdahfi;o"

};

for (int i = 0; i < 10; i++)

{

for (int j = 0; j < 10; j++)

{

DataRow dr = dt.NewRow();

dr[0] = "KK" + i.ToString("d2") + "." + j.ToString("d2");

dr[1] = nameList[j];

if (j % 3 == 0)

{

dr[2] = random.NextDouble().ToString("f3");

}

else

{

dr[2] = i * j - random.Next(0, 30);

}

dr[3] = tempList[j];

dr[4] = random.NextDouble().ToString("f2");

//添加新行

dt.Rows.Add(dr);

}

}

return dt;

}

2.2 创建页脚

一般包含公司信息和页码数。

///

/// 绘制页脚

///

/// 页面

/// 画布

/// 当前页序号

/// 总的页码数

private static void DrawPDFFooter(PdfPage page, XGraphics gfx, int cur, int total)

{

//计算高度

float endY = (float)page.Height - padding_topBottom;

XFont Timefont = new XFont(fontName, 10, XFontStyle.Bold);

//测量字符串大小

XSize size = gfx.MeasureString("Drive Type/", Timefont);

//绘制页脚

gfx.DrawLine(new XPen(XColors.Black, 0.2f),

padding_leftRight,

endY,

page.Width - padding_leftRight,

endY);

endY += 2 + (float)size.Height;

//绘制信息

String footerText = "Test for Windows(C) by 唠嗑一夏 Electric Corporation";

gfx.DrawString(footerText, Timefont, XBrushes.Black, padding_leftRight,

endY);

Timefont = new XFont(fontName, 10, XFontStyle.Regular);

//绘制页码数

footerText = cur.ToString() + "/" + total.ToString();

gfx.DrawString(footerText, Timefont, XBrushes.Black,

(page.Width * 0.9), endY);

}

2.3 完整代码

在这里调用测试数据、页脚函数,项目头和数据内容整合在一起了。

主要使用到GDI的绘制,一直在使用XGraphics 的绘制文本DrawString,绘制直线DrawLine,绘制矩形框DrawRectangle功能。涉及到页面高度,文本高度,文本宽度的计算,计算好了,绘制出来的效果才会好看,需要多尝试一下。 这里需要特别注意这个PdfSharp控件支持的字体,并不是所有字体都支持,如果字体不存在则内容会显示乱码。

using System;

using System.Collections.Generic;

using System.Data;

using System.IO;

using PdfSharp;

using PdfSharp.Drawing;

using PdfSharp.Pdf;

///

/// 生成PDF文档

///

namespace PdfDemo

{

public class PdfSharpHelper

{

static string fontName = "华文宋体"; //华文宋体 Arial

//左右边距

const int padding_leftRight = 30;

//上下边距

const int padding_topBottom = 30;

//示例: http://www.pdfsharp.net/wiki/PDFsharpSamples.ashx?AspxAutoDetectCookieSupport=1

//官网:http://www.pdfsharp.net/

///

/// 绘制头部

///

///

///

///

///

private static float DrawPDFCodeTitle(PdfPage page, XGraphics gfx,float startY)

{

float x = padding_leftRight;

float y = startY;

XFont Titlefont = new XFont(fontName, 9, XFontStyle.Bold);

XSize size = gfx.MeasureString("Param", Titlefont);

float endY = (float)size.Height * 2 + 5;

//绘制标题

gfx.DrawRectangle(XBrushes.LightCyan, new XRect(padding_leftRight, y,

page.Width - 2 * padding_leftRight, endY));

y += (float)size.Height * 2 + 1;

gfx.DrawString(" Parameter", Titlefont, XBrushes.Black, x, y);

x += (float)(page.Width * 0.32);

gfx.DrawString("Value", Titlefont, XBrushes.Black, x, y);

// x += (float)(page.Width * 0.098);

// gfx.DrawString("Infomation", Titlefont, XBrushes.Black, x, y);

x += (float)(page.Width * 0.31);

gfx.DrawString("Setting", Titlefont, XBrushes.Black, x, y);

gfx.DrawString("Default", Titlefont, XBrushes.Black, x, y - size.Height - 1);

return (endY + startY);

}

///

/// 绘制页脚

///

/// 页面

/// 画布

/// 当前页序号

/// 总的页码数

private static void DrawPDFFooter(PdfPage page, XGraphics gfx, int cur, int total)

{

//计算高度

float endY = (float)page.Height - padding_topBottom;

XFont Timefont = new XFont(fontName, 10, XFontStyle.Bold);

//测量字符串大小

XSize size = gfx.MeasureString("Drive Type/", Timefont);

//绘制页脚

gfx.DrawLine(new XPen(XColors.Black, 0.2f),

padding_leftRight,

endY,

page.Width - padding_leftRight,

endY);

endY += 2 + (float)size.Height;

//绘制信息

String footerText = "Test for Windows(C) by 唠嗑一夏 Electric Corporation";

gfx.DrawString(footerText, Timefont, XBrushes.Black, padding_leftRight,

endY);

Timefont = new XFont(fontName, 10, XFontStyle.Regular);

//绘制页码数

footerText = cur.ToString() + "/" + total.ToString();

gfx.DrawString(footerText, Timefont, XBrushes.Black,

(page.Width * 0.9), endY);

}

///

/// 数据表格

///

///

private static DataTable CreateData()

{

DataTable dt = new DataTable();

DataColumn col1 = new DataColumn("Num", typeof(string));

DataColumn col2 = new DataColumn("Name", typeof(string));

DataColumn col3 = new DataColumn("Val", typeof(string));

DataColumn col4 = new DataColumn("Des", typeof(string));

DataColumn col5 = new DataColumn("Set", typeof(string));

dt.Columns.Add(col1);

dt.Columns.Add(col2);

dt.Columns.Add(col3);

dt.Columns.Add(col4);

dt.Columns.Add(col5);

Random random = new Random();

List nameList = new List

{

"A", "BB", "CCC", "D",

"E", "F", "G","H","II",

"JJ", "LL", "M"

};

List tempList = new List

{

"dsd", "sdfdgvre", "Hello", "Gilrs",

"Today", "YYYY", "dfgre","GSD","fdgfer",

"Wesd", "DLG", "fsdahfi;o"

};

for (int i = 0; i < 10; i++)

{

for (int j = 0; j < 10; j++)

{

DataRow dr = dt.NewRow();

dr[0] = "KK" + i.ToString("d2") + "." + j.ToString("d2");

dr[1] = nameList[j];

if (j % 3 == 0)

{

dr[2] = random.NextDouble().ToString("f3");

}

else

{

dr[2] = i * j - random.Next(0, 30);

}

dr[3] = tempList[j];

dr[4] = random.NextDouble().ToString("f2");

//添加新行

dt.Rows.Add(dr);

}

}

return dt;

}

///

/// 创建PDF

///

public static void CreatePdfSharpPDF( )

{

try

{

//获取测试数据

DataTable dataTable = CreateData();

//创建文档对象

PdfDocument doc = new PdfDocument();

//创建空页

PdfPage page = doc.AddPage();

//设置纸张大小

page.Size = PageSize.A4;

List gfxList = new List();

//设置一个画布

XGraphics gfx = XGraphics.FromPdfPage(page);

gfxList.Add(gfx);

const string fontName = "华文宋体";

//设置字体

XFont Titlefont = new XFont(fontName, 14, XFontStyle.Bold);

XFont Timefont = new XFont(fontName, 12, XFontStyle.Regular);

//绘制标题

gfx.DrawString(" Parameter Settings Report(Program)", Titlefont, XBrushes.Black,

new XRect(padding_leftRight, 30, page.Width - padding_leftRight, 30),

XStringFormats.CenterLeft);

//日期

gfx.DrawString(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), Timefont, XBrushes.Black,

new XRect(page.Width * 0.7, 30, page.Width * 0.3 - padding_leftRight, 30),

XStringFormats.BottomRight);

XPen linePen = new XPen(XColor.FromKnownColor(XKnownColor.Black), 0.1);

//绘制线

gfx.DrawLine(linePen,

new XPoint(padding_leftRight, 60), new XPoint(page.Width - padding_leftRight, 60));

//设置字体

Titlefont = new XFont(fontName, 12, XFontStyle.Bold);

Timefont = new XFont(fontName, 10, XFontStyle.Regular);

//测量字体的大小

XSize size = gfx.MeasureString("Program", Titlefont);

XSize size2 = gfx.MeasureString("Drive Type/", Timefont);

float y = 62;

float endY = (float)size.Height + 4 + (float)size2.Height;

//绘制矩形框和字符串

gfx.DrawRectangle(XBrushes.LightCyan, new XRect(padding_leftRight, y, page.Width - 2 * padding_leftRight, endY));

gfx.DrawString(" Program(Drive Selected / Connected)", Titlefont,

XBrushes.Black, padding_leftRight, y, XStringFormat.TopLeft);

y += 4 + (float)size.Height;

gfx.DrawString(" Drive Type/Model: ", Timefont,

XBrushes.Black, padding_leftRight, y, XStringFormat.TopLeft);

y += 4 + (float)size2.Height;

gfx.DrawLine(linePen,

new XPoint(padding_leftRight, y), new XPoint(page.Width - padding_leftRight, y));

y += 4;

gfx.DrawString(" Project: ", Titlefont,

XBrushes.Black, padding_leftRight, y, XStringFormat.TopLeft);

y += 4 + (float)size.Height;

gfx.DrawLine(linePen,

new XPoint(padding_leftRight, y), new XPoint(page.Width - padding_leftRight, y));

y += 4;

Titlefont = new XFont(fontName, 11, XFontStyle.Bold);

gfx.DrawString(" Information ", Titlefont,

XBrushes.Black, padding_leftRight, y, XStringFormat.TopLeft);

y += 100;

//项目的标题

y = DrawPDFCodeTitle(page, gfx, y) + 10;

//绘制功能码的字体

XFont funFont = new XFont(fontName, 9);

XFont FunBoldFont = new XFont(fontName, 9, XFontStyle.Underline | XFontStyle.Bold);

//字体的高度

XSize funcSize = gfx.MeasureString("KK00.00", funFont);

XSize funcBoldSize = gfx.MeasureString("KK00.00", FunBoldFont);

int count = dataTable.Rows.Count;

string str = "";

string strBak = "";

int j = 0;

for (int i = 0; i < count; i++)

{//遍历dataTable数据

if ((y + funcSize.Height + 3) > (page.Height - padding_topBottom))

{//换页

page = doc.Pages.Add();

page.Size = PageSize.A4;

gfx = XGraphics.FromPdfPage(page);

gfxList.Add(gfx);

//绘制表头

y = DrawPDFCodeTitle(page, gfx, 10) + 10;

}

DataRow dataRow = dataTable.Rows[i];

strBak = dataRow[0].ToString().Substring(0, 4);

if (strBak != str)

{//绘制组别

str = strBak;

string converStr = strBak ;

j++;

funcBoldSize = gfx.MeasureString(converStr, FunBoldFont);

y += (float)funcBoldSize.Height + 6;

gfx.DrawString(converStr, FunBoldFont, XBrushes.Black, padding_leftRight, y);

y += 2;

i--;

continue;

}

// else

{//绘制

string tempStr = dataRow[0].ToString() + " " + dataRow[1].ToString();

funcSize = gfx.MeasureString(tempStr, funFont);

y += (float)funcSize.Height + 3;

if ((y + funcSize.Height + 3) > (page.Height - padding_topBottom))

{//换页

page = doc.Pages.Add();

page.Size = PageSize.A4;

gfx = XGraphics.FromPdfPage(page);

gfxList.Add(gfx);

//绘制表头

y = DrawPDFCodeTitle(page, gfx, 10) + 10;

}

//序号+描述

float widthX = padding_leftRight;

gfx.DrawString(tempStr, funFont, XBrushes.Black, widthX, y);

//当前值

widthX += (float)(page.Width * 0.32);

gfx.DrawString(dataRow[2].ToString(), funFont, XBrushes.Black, widthX, y);

//设置值

widthX += (float)(page.Width * 0.31);

gfx.DrawString(dataRow[4].ToString(), funFont, XBrushes.Black, widthX, y);

}

}

gfx = null;

int Total = doc.PageCount;

for (int i = 0; i < Total; i++)

{//绘制页脚

DrawPDFFooter(page, gfxList[i], i + 1, Total);

}

string path = "PdfSharpDemo.pdf";

doc.Save(path);

}

catch (Exception ex)

{

}

}

}

}

效果图:也可以看文章最前面的动图

小结

PdfSharp创建PDF文档使用的是Drawing方式,用户可以通过绘制来实现自己各式各样的需求。 而且PdfSharp是免费开源的,这就秒杀了一大波其它付费的控件了。与Aspose.Pdf相比,PdfSharp生成PDF文件的速度快多了。

附录:

PdfSharp官网链接:http://www.pdfsharp.com/PDFsharp/ PdfSharp的使用Demo:http://www.pdfsharp.net/wiki/PDFsharpSamples.ashx?AspxAutoDetectCookieSupport=1

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: