C#生成pdf -- iText7 设置自定义字体和表格
阅读原文时间:2023年07月13日阅读:3

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列

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章