<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      .NET使用QuestPDF高效地生成PDF文檔

      前言

      在.NET平臺中操作生成PDF的類庫有很多如常見的有iTextSharp、PDFsharp、Aspose.PDF等,今天我們分享一個用于生成PDF文檔的現代開源.NET庫:QuestPDF,本文將介紹QuestPDF并使用它快速實現發票PDF文檔生成功能。

      QuestPDF介紹

      QuestPDF 是一個用于生成 PDF 文檔的現代開源 .NET 庫。QuestPDF 由簡潔易用的 C# Fluent API 提供全面的布局引擎。輕松生成 PDF 報告、發票、導出等。QuestPDF它提供了一個布局引擎,在設計時考慮了完整的分頁支持。與其他庫不同,它不依賴于 HTML 到 PDF 的轉換,這在許多情況下是不可靠的。相反,它實現了自己的布局引擎,該引擎經過優化,可以滿足所有與分頁相關的要求。

      QuestPDF License

      分為社區版、專業版、和企業版。

      項目源代碼

      創建一個控制臺應用

      創建一個名為QuestPDFTest的控制臺應用。

      安裝QuestPDF Nuget包

      搜索:QuestPDF包進行安裝。

       

      快速實現發票PDF文檔生成

      創建InvoiceModel

      namespace QuestPDFTest
      {
          public class InvoiceModel
          {

              /// <summary>
              /// 發票號碼
              /// </summary>
              public int InvoiceNumber { get; set; }

              /// <summary>
              /// 發票開具日期
              /// </summary>
              public DateTime IssueDate { get; set; }

              /// <summary>
              /// 發票到期日期
              /// </summary>
              public DateTime DueDate { get; set; }

              /// <summary>
              /// 賣方公司名稱
              /// </summary>
              public string SellerCompanyName { get; set; }

              /// <summary>
              /// 買方公司名稱
              /// </summary>
              public string CustomerCompanyName { get; set; }

              /// <summary>
              /// 訂單消費列表
              /// </summary>
              public List<OrderItem> OrderItems { get; set; }

              /// <summary>
              /// 備注
              /// </summary>
              public string Comments { get; set; }
          }

          public class OrderItem
          {
              /// <summary>
              /// 消費類型
              /// </summary>
              public string Name { get; set; }

              /// <summary>
              /// 消費金額
              /// </summary>
              public decimal Price { get; set; }

              /// <summary>
              /// 消費數量
              /// </summary>
              public int Quantity { get; set; }
          }
      }

      CreateInvoiceDetails

      namespace QuestPDFTest
      {
          public class CreateInvoiceDetails
          {
              private static readonly Random _random = new Random();

              public enum InvoiceType
              {
                  餐飲費,
                  交通費,
                  住宿費,
                  日用品,
                  娛樂費,
                  醫療費,
                  通訊費,
                  教育費,
                  裝修費,
                  旅游費
              }

              /// <summary>
              /// 獲取發票詳情數據
              /// </summary>
              /// <returns></returns>
              public static InvoiceModel GetInvoiceDetails()
              {
                  return new InvoiceModel
                  {
                      InvoiceNumber = _random.Next(1_000, 10_000),
                      IssueDate = DateTime.Now,
                      DueDate = DateTime.Now + TimeSpan.FromDays(14),
                      SellerCompanyName = "追逐時光者",
                      CustomerCompanyName = "DotNetGuide技術社區",
                      OrderItems = Enumerable
                      .Range(1, 20)
                      .Select(_ => GenerateRandomOrderItemInfo())
                      .ToList(),
                      Comments = "DotNetGuide技術社區是一個面向.NET開發者的開源技術社區,旨在為開發者們提供全面的C#/.NET/.NET Core相關學習資料、技術分享和咨詢、項目推薦、招聘資訊和解決問題的平臺。在這個社區中,開發者們可以分享自己的技術文章、項目經驗、遇到的疑難技術問題以及解決方案,并且還有機會結識志同道合的開發者。我們致力于構建一個積極向上、和諧友善的.NET技術交流平臺,為廣大.NET開發者帶來更多的價值和成長機會。"
                  };
              }

              /// <summary>
              /// 訂單信息生成
              /// </summary>
              /// <returns></returns>
              private static OrderItem GenerateRandomOrderItemInfo()
              {
                  var types = (InvoiceType[])Enum.GetValues(typeof(InvoiceType));
                  return new OrderItem
                  {
                      Name = types[_random.Next(types.Length)].ToString(),
                      Price = (decimal)Math.Round(_random.NextDouble() * 100, 2),
                      Quantity = _random.Next(1, 10)
                  };
              }
          }
      }

      CreateInvoiceDocument

      using QuestPDF.Fluent;
      using QuestPDF.Helpers;
      using QuestPDF.Infrastructure;

      namespace QuestPDFTest
      {
          public class CreateInvoiceDocument : IDocument
          {
              /// <summary>
              /// 獲取Logo的的Image對象
              /// </summary>
              public static Image LogoImage { get; } = Image.FromFile("dotnetguide.png");

              public InvoiceModel Model { get; }

              public CreateInvoiceDocument(InvoiceModel model)
              {
                  Model = model;
              }

              public DocumentMetadata GetMetadata() => DocumentMetadata.Default;

              public void Compose(IDocumentContainer container)
              {
                  container
                      .Page(page =>
                      {
                          //設置頁面的邊距
                          page.Margin(50);

                          //字體默認大小18號字體
                          page.DefaultTextStyle(x => x.FontSize(18));

                          //頁眉部分
                          page.Header().Element(BuildHeaderInfo);

                          //內容部分
                          page.Content().Element(BuildContentInfo);

                          //頁腳部分
                          page.Footer().AlignCenter().Text(text =>
                          {
                              text.CurrentPageNumber();
                              text.Span(" / ");
                              text.TotalPages();
                          });
                      });
              }

              #region 構建頁眉部分
              void BuildHeaderInfo(IContainer container)
              {
                  container.Row(row =>
                  {
                      row.RelativeItem().Column(column =>
                      {
                          column.Item().Text($"發票編號 #{Model.InvoiceNumber}").FontFamily("fangsong").FontSize(20).SemiBold().FontColor(Colors.Blue.Medium);

                          column.Item().Text(text =>
                          {
                              text.Span("發行日期: ").FontFamily("fangsong").FontSize(13).SemiBold();
                              text.Span($"{Model.IssueDate:d}");
                          });

                          column.Item().Text(text =>
                          {
                              text.Span("終止日期: ").FontFamily("fangsong").FontSize(13).SemiBold();
                              text.Span($"{Model.DueDate:d}");
                          });
                      });

                      //在當前行的常量項中插入一個圖像
                      row.ConstantItem(130).Image(LogoImage);
                  });
              }

              #endregion

              #region 構建內容部分

              void BuildContentInfo(IContainer container)
              {
                  container.PaddingVertical(40).Column(column =>
                  {
                      column.Spacing(20);

                      column.Item().Row(row =>
                      {
                          row.RelativeItem().Component(new AddressComponent("賣方公司名稱", Model.SellerCompanyName));
                          row.ConstantItem(50);
                          row.RelativeItem().Component(new AddressComponent("客戶公司名稱", Model.CustomerCompanyName));
                      });

                      column.Item().Element(CreateTable);

                      var totalPrice = Model.OrderItems.Sum(x => x.Price * x.Quantity);
                      column.Item().PaddingRight(5).AlignRight().Text($"總計: {totalPrice}").FontFamily("fangsong").SemiBold();

                      if (!string.IsNullOrWhiteSpace(Model.Comments))
                          column.Item().PaddingTop(25).Element(BuildComments);
                  });
              }

              /// <summary>
              /// 創建表格
              /// </summary>
              /// <param name="container">container</param>
              void CreateTable(IContainer container)
              {
                  var headerStyle = TextStyle.Default.SemiBold();

                  container.Table(table =>
                  {
                      table.ColumnsDefinition(columns =>
                      {
                          columns.ConstantColumn(25);
                          columns.RelativeColumn(3);
                          columns.RelativeColumn();
                          columns.RelativeColumn();
                          columns.RelativeColumn();
                      });

                      table.Header(header =>
                      {
                          header.Cell().Text("#").FontFamily("fangsong");
                          header.Cell().Text("消費類型").Style(headerStyle).FontFamily("fangsong");
                          header.Cell().AlignRight().Text("花費金額").Style(headerStyle).FontFamily("fangsong");
                          header.Cell().AlignRight().Text("數量").Style(headerStyle).FontFamily("fangsong");
                          header.Cell().AlignRight().Text("總金額").Style(headerStyle).FontFamily("fangsong");
                          //設置了表頭單元格的屬性
                          header.Cell().ColumnSpan(5).PaddingTop(5).BorderBottom(1).BorderColor(Colors.Black);
                      });

                      foreach (var item in Model.OrderItems)
                      {
                          var index = Model.OrderItems.IndexOf(item) + 1;

                          table.Cell().Element(CellStyle).Text($"{index}").FontFamily("fangsong");
                          table.Cell().Element(CellStyle).Text(item.Name).FontFamily("fangsong");
                          table.Cell().Element(CellStyle).AlignRight().Text($"{item.Price}").FontFamily("fangsong");
                          table.Cell().Element(CellStyle).AlignRight().Text($"{item.Quantity}").FontFamily("fangsong");
                          table.Cell().Element(CellStyle).AlignRight().Text($"{item.Price * item.Quantity}").FontFamily("fangsong");
                          static IContainer CellStyle(IContainer container) => container.BorderBottom(1).BorderColor(Colors.Grey.Lighten2).PaddingVertical(5);
                      }
                  });
              }

              #endregion

              #region 構建頁腳部分

              void BuildComments(IContainer container)
              {
                  container.ShowEntire().Background(Colors.Grey.Lighten3).Padding(10).Column(column =>
                  {
                      column.Spacing(5);
                      column.Item().Text("DotNetGuide技術社區介紹").FontSize(14).FontFamily("fangsong").SemiBold();
                      column.Item().Text(Model.Comments).FontFamily("fangsong");
                  });
              }

              #endregion
          }

          public class AddressComponent : IComponent
          {
              private string Title { get; }
              private string CompanyName { get; }

              public AddressComponent(string title, string companyName)
              {
                  Title = title;
                  CompanyName = companyName;
              }

              public void Compose(IContainer container)
              {
                  container.ShowEntire().Column(column =>
                  {
                      column.Spacing(2);

                      column.Item().Text(Title).FontFamily("fangsong").SemiBold();
                      column.Item().PaddingBottom(5).LineHorizontal(1);
                      column.Item().Text(CompanyName).FontFamily("fangsong");
                  });
              }
          }
      }

      Program

      using QuestPDF;
      using QuestPDF.Fluent;
      using QuestPDF.Infrastructure;

      namespace QuestPDFTest
      {
          internal class Program
          {
              static void Main(string[] args)
              {
                  // 1、請確保您有資格使用社區許可證,不設置的話會報異常。
                  Settings.License = LicenseType.Community;

                  // 2、禁用QuestPDF庫中文本字符可用性的檢查
                  Settings.CheckIfAllTextGlyphsAreAvailable = false;

                  // 3、PDF Document 創建
                  var invoiceSourceData = CreateInvoiceDetails.GetInvoiceDetails();
                  var document = new CreateInvoiceDocument(invoiceSourceData);

                  // 4、生成 PDF 文件并在默認的查看器中顯示
                  document.GeneratePdfAndShow();
              }
          }
      }

      完整示例源代碼

      https://github.com/YSGStudyHards/QuestPDFTest

      示例運行效果圖

      注意問題

      中文報異常

      QuestPDF.Drawing.Exceptions.DocumentDrawingException:“Could not find an appropriate font fallback for glyph: U-53D1 '發'. Font families available on current environment that contain this glyph: Microsoft JhengHei, Microsoft JhengHei UI, Microsoft YaHei, Microsoft YaHei UI, SimSun, NSimSun, DengXian, FangSong, KaiTi, SimHei, FZCuHeiSongS-B-GB. Possible solutions: 1) Use one of the listed fonts as the primary font in your document. 2) Configure the fallback TextStyle using the 'TextStyle.Fallback' method with one of the listed fonts. You can disable this check by setting the 'Settings.CheckIfAllTextGlyphsAreAvailable' option to 'false'. However, this may result with text glyphs being incorrectly rendered without any warning.”

      加上這段代碼:

      // 2、禁用QuestPDF庫中文本字符可用性的檢查
      Settings.CheckIfAllTextGlyphsAreAvailable = false;

      原因:

      默認情況下,使用 QuestPDF 生成 PDF 文檔時,它會檢查所使用的字體是否支持文本中的所有字符,并在發現不能顯示的字符時輸出一條警告消息。這個選項可以確保文本中的所有字符都能正確地顯示在生成的 PDF 文件中。

      中文亂碼問題

      解決方案:

      假如Text("")中為漢字一定要在后面加上FontFamily("fangsong")[仿宋字體]或FontFamily("simhei")[黑體字體],否則中文無法正常顯示。

      項目源碼地址

      更多項目實用功能和特性歡迎前往項目開源地址查看??,別忘了給項目一個Star支持??。

      GitHub地址:https://github.com/QuestPDF/QuestPDF

      文檔地址:https://www.questpdf.com/api-reference/

      優秀項目和框架精選

      該項目已收錄到C#/.NET/.NET Core優秀項目和框架精選中,關注優秀項目和框架精選能讓你及時了解C#、.NET和.NET Core領域的最新動態和最佳實踐,提高開發工作效率和質量。坑已挖,歡迎大家踴躍提交PR推薦或自薦(讓優秀的項目和框架不被埋沒??)。

      https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.md

      DotNetGuide技術社區交流群

      • DotNetGuide技術社區是一個面向.NET開發者的開源技術社區,旨在為開發者們提供全面的C#/.NET/.NET Core相關學習資料、技術分享和咨詢、項目推薦、招聘資訊和解決問題的平臺。
      • 在這個社區中,開發者們可以分享自己的技術文章、項目經驗、遇到的疑難技術問題以及解決方案,并且還有機會結識志同道合的開發者。
      • 我們致力于構建一個積極向上、和諧友善的.NET技術交流平臺,為廣大.NET開發者帶來更多的價值和成長機會。

      歡迎加入DotNetGuide技術社區微信交流群??

      posted @ 2024-01-18 08:43  追逐時光者  閱讀(5629)  評論(16)    收藏  舉報
      主站蜘蛛池模板: 人人妻一区二区三区| 亚洲成av一区二区三区| 男人猛躁进女人免费播放| 在线视频一区二区三区色| 亚洲av无码国产在丝袜线观看| 久久88香港三级台湾三级播放| 国产精品欧美福利久久| 久久精品国产中文字幕| 大又大又粗又硬又爽少妇毛片 | 国产极品美女高潮无套| 国产色无码精品视频免费| 国产午夜A理论毛片| av亚洲一区二区在线| 亚洲熟妇丰满多毛xxxx| 欧洲亚洲色一区二区色99| 猫咪社区免费资源在线观看| 少妇被无套内谢免费看| 亚洲人成人日韩中文字幕| 欧美成人猛片aaaaaaa| 天堂va蜜桃一区二区三区| 午夜福利偷拍国语对白| 色吊丝中文字幕在线观看| 色777狠狠狠综合| 免费看欧美日韩一区二区三区| 人妻少妇精品视频专区| jizzjizz少妇亚洲水多| 九九热视频精选在线播放| 大姚县| 日韩精品在线观看一二区| 欧美巨大巨粗黑人性aaaaaa| 欧美裸体xxxx极品| 亚洲一区二区三区在线| 亚洲人成人影院在线观看| 中国帅小伙gaysextubevideo| 日韩在线视频一区二区三| 亚洲欧洲日产国无高清码图片| 日本一区不卡高清更新二区 | 高清无码18| 久久碰国产一区二区三区| 电影在线观看+伦理片| 92国产精品午夜福利|