C#生成pdf -- iText7 设置自定义字体和表格

摘要:
itextsharp已经不再更新,由iText7来替代安装nuget安装itext7注册自定义字体下载字体文件.ttc或.ttf到项目目录,设置更新则拷贝到输出目录,这样构建的时候会把字体文件拷贝过去windows系统自带黑体,可以直接复制到项目目录,其路径是C:WindowsFontssimhei.ttf因为字体注册只需要一次,所以建议放到StartUp中.其中的simhei.ttf换为你的字体

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

安装

nuget 安装 itext7

C#生成pdf -- iText7 设置自定义字体和表格第1张

注册自定义字体

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

C#生成pdf -- iText7 设置自定义字体和表格第2张

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

C:WindowsFontssimhei.ttf

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

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

C#生成pdf -- iText7 设置自定义字体和表格第3张

新建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 classOrderDto
    {
        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 classProductDto
    {
        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")]
        publicIActionResult 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 = newTable(headerTexts.Length)  // 设置表格列数
                .SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER)
                ;
            //添加表头
            foreach (var header inheaderTexts)
            {
                table.AddHeaderCell(newCell()
                    .Add(newParagraph(header))
                    .SetBold()//设置粗体
);
            }
       
var orders = new[] { newOrderDto { Name = "法外", Gender = "", Address = "江苏省南京市江宁区梧桐路325号", Phone = "13545781245", Remark = "就这?", Products = new List<ProductDto>{ new ProductDto { Code="XGRD102", Name = "格子衫", Category = "男装", Unit = "", Sku = "紫色", Price = 39, Quantity = 1} } }, newOrderDto { 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}, } }, newOrderDto { 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(newCell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(new Paragraph(orders[i].Products[0].Name)//产品名称 )) .AddCell(newCell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(new Paragraph(orders[i].Products[0].Category)) .SetMinWidth(25) )//分类 .AddCell(newCell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(new Paragraph(orders[i].Products[0].Unit)//单位 )) .AddCell(newCell() .SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(new Paragraph(orders[i].Products[0].Sku)//规格 .SetMinWidth(25) )) .AddCell(newCell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(new Paragraph(orders[i].Products[0].Price.ToString("0.00"))//售价 )) .AddCell(newCell() .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(newParagraph(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(newCell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(new Paragraph(orders[i].Products[j].Name)//产品名称 )) .AddCell(newCell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(newParagraph(orders[i].Products[j].Category)) .SetMinWidth(25) )//分类 .AddCell(newCell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(new Paragraph(orders[i].Products[j].Unit)//单位 )) .AddCell(newCell() .SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(new Paragraph(orders[i].Products[j].Sku)//规格 .SetMinWidth(25) )) .AddCell(newCell().SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.MIDDLE) .Add(new Paragraph(orders[i].Products[j].Price.ToString("0.00"))//售价 )) .AddCell(newCell() .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"); }

结果如下

C#生成pdf -- iText7 设置自定义字体和表格第4张

有几个要点

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

免责声明:文章转载自《C#生成pdf -- iText7 设置自定义字体和表格》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[转]HEX文件格式PhpStorm 8.x/9.x 快捷键设置/个性化设置,如何多项目共存?如何更换主题?下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

消息中间件系列三:使用RabbitMq原生Java客户端进行消息通信(消费者(接收方)自动确认模式、消费者(接收方)自行确认模式、生产者(发送方)确认模式)

准备工作: 1)安装RabbitMQ,参考文章:消息中间件系列二:RabbitMQ入门(基本概念、RabbitMQ的安装和运行) 2.)分别新建名为OriginalRabbitMQProducer和OriginalRabbitMQConsumer的maven工程 在pom.xml文件里面引入如下依赖: <dependency>...

Flutter实战视频-移动电商-39.路由_Fluro的路由配置和静态化

39.路由_Fluro的路由配置和静态化 handler只是单个路由的配置,这节课我们要学习路由的整体配置 整体配置 新建routers.dart文件来做整体配置 detailsHandler就是我们在router_handler里面定义的detailsHandler 当路由不存在的时候,给用户一个反馈。router.notFoundHandler 这...

把dataset数据转换成json的格式通用方法

/// <summary>        /// 把dataset数据转换成json的格式        /// </summary>        /// <param name="ds">dataset数据集</param>        /// <returns>json格式的字符串<...

vba Excel连接数据库

PostgreSql: 第一步 在网上下载postres的驱动程序,之后安装,下载地址:https://www.devart.com/odbc/postgresql/download.html 第二步 创建ODBC数据源 点击“开始-》控制面板-》管理工具-》数据源(ODBC)-》用户DSN-》添加” 安装上图配置好之后写入VBA代码并导入包文件...

【java虚拟机】jvm内存模型

作者:pengjunlee原文链接:https://blog.csdn.net/pengjunlee/article/details/71909239 目录 一、运行时数据区域   1、程序计数器   2、Java 虚拟机栈   3、本地方法栈   4、Java 堆   5、方法区   6、运行时常量池   7、直接内存 二、OutOfMemoryErro...

Android中关于日期时间与时区的使用总结

原文引自:http://www.2cto.com/kf/201312/266908.html 在开发Android的过程中,出现过几次由于日期时间导致的问题,而且主要是由于时区的原因导致,所以一直想总结一下,形成一个良好的开发规范。 一、Unix时间戳 Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(...