itextsharp已经不再更新,由iText 7来替代

安装

nuget 安装 itext7

注册自定义字体

下载字体文件 .ttc或.ttf到项目目录,设置更新则拷贝到输出目录,这样构建的时候会把字体文件拷贝过去

windows系统自带黑体, 可以直接复制到项目目录, 其路径是

C:\Windows\Fonts\simhei.ttf

因为字体注册只需要一次,所以建议放到StartUp中. 其中的simhei.ttf换为你的字体文件

iText.Kernel.Font.PdfFontFactory.Register("simhei.ttf");

新建pdf文档

using PdfWriter writer = new ("list.pdf");
PdfDocument pdf = new (writer);
Document doc = new (pdf);

PdfWriter可以传入pdf文件目标路径或者Stream,如果不想保存到本地,那用MemoryStream保存在内存中即可. 后边的例子我们就是直接用MemoryStream来保存数据

设置字体

PdfFont sysFont = PdfFontFactory.CreateRegisteredFont("simhei", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED, true);
doc.SetFont(sysFont)
.SetFontSize(12);//设置字体大小

示例

public class OrderDto
{
public string Name { get; set; } public string Gender { get; set; } public string Address { get; set; } public string Phone { get; set; } public List<ProductDto> Products { get; set; } public string Remark { get; set; }
} public class ProductDto
{
public string Code { get; set; } public string Name { get; set; } public string Category { get; set; } public string Unit { get; set; } public string Sku { get; set; } public decimal Price { get; set; } public int Quantity { get; set; }
}
        [HttpGet("pdf")]
public IActionResult ExportPdf()
{
MemoryStream stream = new ();
PdfWriter writer = new (stream);
PdfDocument pdf = new (writer);
Document doc = new (pdf); //黑体
PdfFont sysFont = PdfFontFactory.CreateRegisteredFont("simhei", PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED, true);
doc.SetFont(sysFont)
.SetFontSize(12);//设置字体大小 doc.Add(new Paragraph("订单列表")
.SetBold()//粗体
.SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER)//居中
); var headerTexts = new[] {
"序号", "姓名", "性别", "居住地址", "联系电话",
"货号", "产品名称", "分类", "单位", "规格", "售价", "数量",
"备注"
};
var table = new Table(headerTexts.Length) // 设置表格列数
.SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER)
;
//添加表头
foreach (var header in headerTexts)
{
table.AddHeaderCell(new Cell()
.Add(new Paragraph(header))
.SetBold()//设置粗体
);
}
       
        

var orders = new[]
{
new OrderDto
{
Name = "法外", Gender = "男", Address = "江苏省南京市江宁区梧桐路325号", Phone = "13545781245", Remark = "就这?",
Products = new List<ProductDto>{ new ProductDto { Code="XGRD102", Name = "格子衫", Category = "男装", Unit = "件", Sku = "紫色", Price = 39, Quantity = 1} }
},
new OrderDto
{
Name = "狂徒", Gender = "男", Address = "重庆市江北区朝鸽大道北777号", Phone = "15845568956", Remark = "代码敲得好,备胎当到老",
Products = new List<ProductDto>
{
new ProductDto { Code="FUS458", Name = "Amd R7 5800X", Category = "电子产品", Unit = "个", Sku = "盒装", Price = 2499, Quantity = 1},
new ProductDto { Code="TFES982", Name = "程序员帽子", Category = "配饰", Unit = "件", Sku = "绿色", Price = 666, Quantity = 1},
}
},
new OrderDto
{
Name = "张三", Gender = "女", Address = "辽宁省大连市甘井子区伞兵路2333号", Phone = "15952415263", Remark = "rnm, 退钱!!!",
Products = new List<ProductDto>{ new ProductDto { Code="TOP10", Name = "Rnm,退钱同款长袖", Category = "男装", Unit = "件", Sku = "红色", Price = 69, Quantity = 1} }
},
}; for (int i = 0; i < orders.Length; i++)
{
int rowSpan = orders[i].Products.Count;//商品行有多少个,基本信息列就要跨对应多少行
table.StartNewRow();//第一列开启新行
table
.AddCell(new Cell(rowSpan,1).Add(new Paragraph((i + 1).ToString()))//序号
.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)) .AddCell(new Cell(rowSpan, 1).Add(new Paragraph(orders[i].Name)).SetMinWidth(25)//姓名 设置最小列宽25,方便名字横向显示
.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)) .AddCell(new Cell(rowSpan, 1).Add(new Paragraph(orders[i].Gender))//性别
.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)) .AddCell(new Cell(rowSpan, 1).Add(new Paragraph(orders[i].Address))//居住地址
.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)) .AddCell(new Cell(rowSpan, 1).Add(new Paragraph(orders[i].Phone))//联系电话
.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)); //添加一行商品信息 (因为table只能按顺序从左到右一个cell一个cell地加)
table
.AddCell(new Cell(1,1).SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[0].Code)//货号
)) .AddCell(new Cell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[0].Name)//产品名称
)) .AddCell(new Cell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[0].Category))
.SetMinWidth(25)
)//分类 .AddCell(new Cell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[0].Unit)//单位
)) .AddCell(new Cell()
.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[0].Sku)//规格
.SetMinWidth(25)
)) .AddCell(new Cell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[0].Price.ToString("0.00"))//售价
)) .AddCell(new Cell()
.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[0].Quantity.ToString())//数量
)) .AddCell(new Cell(rowSpan, 1).SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Remark))
);//备注 //商品行大于1, 需要添加多行商品信息
if (orders[i].Products.Count > 1)
{
for (int j = 1; j < orders[i].Products.Count; j++)
{
table
.AddCell(new Cell(1, 1).SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[j].Code)//货号
)) .AddCell(new Cell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[j].Name)//产品名称
)) .AddCell(new Cell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[j].Category))
.SetMinWidth(25)
)//分类 .AddCell(new Cell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[j].Unit)//单位
)) .AddCell(new Cell()
.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[j].Sku)//规格
.SetMinWidth(25)
)) .AddCell(new Cell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[j].Price.ToString("0.00"))//售价
)) .AddCell(new Cell()
.SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE)
.Add(new Paragraph(orders[i].Products[j].Quantity.ToString())//数量
));
}
}
} doc.Add(table);
pdf.Close();//记得关闭PdfDocument和PdfWriter
writer.Close();
return File(stream.ToArray(), "application/pdf");
}

结果如下

有几个要点

  1. 单元格合并是通过跨行或跨列来实现的, new Cell(2, 2)表示此单元格跨2行 2列
  2. 单元格设置居中最好是放在Add(new Paragraph("xx"))之前
  3. 添加单元格只能从左到右一个一个地加,所以有合并行的时候要把第一行全部添加完再添加下边的几行,如图所示.
  4. 新的一行要先调用table.StartNewRow()  然后table.AddCell()才会添加到新行
  5. 表格的列数是在new Table(13) 时传入的, 传入13就表示有13列

C#生成pdf -- iText7 设置自定义字体和表格的更多相关文章

  1. Android Studio设置自定义字体

    Android Studio设置自定义字体 (1)进入设置页面,File->Settings (2)自定义字体Editor->Colors&Fonts->Font (3)点击 ...

  2. poi生成excel整理(设置边框/字体/颜色/加粗/居中/)

    转: poi生成excel整理(设置边框/字体/颜色/加粗/居中/) 2016年12月02日 11:05:23 吃奶的牛 阅读数:34324   HSSFWorkbook wb = new HSSFW ...

  3. freemark+ITextRenderer 生成PDF,设置pdf的页面大小

    在html中添加样式,仅生成pdf是生效,浏览器展示时是不会生效的: <style> @page{ size : 200mm  300 mm;   } </style>

  4. c# iText 生成PDF 有文字,图片,表格,文字样式,对齐方式,页眉页脚,等等等,

    #region 下载说明书PDF protected void lbtnDownPDF_Click(object sender, EventArgs e) { int pid = ConvertHel ...

  5. PHP生成PDF并转换成图片爬过的坑

    需求描述:根据订单通过模板合同生成新的PDF合同通过e签宝签约后转为图片给用户下载. 需求整理: 1.如何生成PDF文件:使用TCPDF扩展生成.思考: ⑴为了方便将模板中的固定占位符替换为订单中的内 ...

  6. CSS自定义字体的实现,前端实现字体压缩

    CSS中使用自定义字体,首先需要下载你需要的字体ttf或者otf文件 这里推荐一个网站:http://www.zitixiazai.org/ /********css中********/ @font- ...

  7. iOS自定义字体

    1.下载字体库,如:DINCond-Bold.otf 2.双击,在mac上安装 3.把下载的字体库拖入工程中: 4.配置info.plist文件 5.xib方式设置自定义字体:Font选Custom, ...

  8. CSS怎么在项目里引入自定义字体(@font-face)

    前言: 以前我一直用内置的默认字体给文字设置字体,直到一天UI妹纸给了我下面的字体    当时我是蒙蔽的,这个字体的效果如下 默认字体并无该字体,直接设置是没有效果的,这时就需要用到自定义字体了 下面 ...

  9. Java使用iText7生成PDF

    前言 我们之前使用js库html2canvas + jspdf实现html转PDF.图片,并下载(详情请戳:html页面转PDF.图片操作记录),大致原理是将页面塞到画布里,以图片的方式放到PDF中, ...

随机推荐

  1. 大爽Python入门教程 2-4 练习

    大爽Python入门公开课教案 点击查看教程总目录 方位输出 第一章有一个思考题,方位变换: 小明同学站在平原上,面朝北方,向左转51次之后(每次只转90度), 小明面朝哪里?小明转过了多少圈? (3 ...

  2. [luogu7476]苦涩

    维护线段树,在其每一个节点上维护一个set(可重),以及子树内所有set的最大值 考虑下传标记,如果将所有元素全部下传复杂度显然不正确,但注意到我们仅关心于其中的最大值,即仅需要将最大值下传即可 其有 ...

  3. [noi707]LP

    (以下用$Sa=\sum_{j=1}^{i}xi\cdot ai$,Sb和Sc同理)令f[i][x]表示前i个数,$Sa\le x\le Sb$时最小的Sc考虑第i个数是否选择,可以得到递推式$f[i ...

  4. [atAGC048F]01 Record

    先将这个序列翻转,贪心找到最长的'101010--'的形式的子序列并删除,重复此过程并记这些字符串长度依次为$l_{1},l_{2},...,l_{n}$,若最终还有字符剩余则一定无解 假设$S$中元 ...

  5. 1、使用ValueOperations操作redis(String字符串)

    文章来源:https://www.cnblogs.com/shiguotao-com/p/10559997.html 方法 c参数 s说明   void set(K key, V value); ke ...

  6. 【NetWork】-- 网络原理

    2019-07-18  21:00:25  by冲冲 1. 网络拓扑 把网络中的计算机和通信设备抽象为一个点,把传输介质抽象为一条线,由点和线组成的几何图形就是计算机网络的拓扑结构(Network T ...

  7. Python技法1:变长和定长序列拆分

    Python中的任何序列(可迭代的对象)都可以通过赋值操作进行拆分,包括但不限于元组.列表.字符串.文件.迭代器.生成器等. 元组拆分 元组拆分是最为常见的一种拆分,示例如下: p = (4, 5) ...

  8. vue-cli的安装步骤

    1.安装Node.js 在Node.js官网 https://nodejs.org/zh-cn/下载安装包,修改安装路径到其它盘,如 G:\Program Files 2.设置 cnpm的下载路径和缓 ...

  9. Codeforces 375C - Circling Round Treasures(状压 dp+最短路转移)

    题面传送门 注意到这题中宝藏 \(+\) 炸弹个数最多只有 \(8\) 个,故考虑状压,设 \(dp[x][y][S]\) 表示当前坐标为 \((x,y)\),有且仅有 \(S\) 当中的物品被包围在 ...

  10. NextDenovo 组装基因组

    NextDenovo 是有武汉未来组团队开发出来用于组装ONT,Pacbio, HIFI (默认参数可对60-100X数据更有效),可通过correct--assemble对其进行组装.组装后,每个碱 ...