C#生成pdf -- iText7 設置自定義字體和表格

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列

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章