使用C#创建PDF文档的完整教程(文本、图片、形状与表格插入)

好的,这是一份使用 C# 创建 PDF 文档的完整教程,涵盖了文本、图片、形状和表格的插入。我们将使用一个强大且流行的库 ​iTextSharp​(或其社区版分支 ​iText 7 Community)来实现。本教程将以 ​iText 7​ 为核心,因为它代表了 iText 的未来,并且 API 更现代。

图片[1]_使用C#创建PDF文档的完整教程(文本、图片、形状与表格插入)_知途无界

第一步:环境准备与安装 NuGet 包

首先,你需要一个 C# 开发环境(如 Visual Studio 2022+)。我们将通过 NuGet 包管理器来安装必要的库。

  1. 在 Visual Studio 中创建一个新的 ​Console App (.NET Core)​​ 或 ​Console App (.NET Framework)​​ 项目。
  2. 在解决方案资源管理器中,右键单击你的项目,选择 ​​“管理 NuGet 程序包”​
  3. 切换到 ​​“浏览”​​ 选项卡,搜索 ​**itext7**。
  4. 找到 ​**iText7**​ 并点击安装。通常还会同时安装 itext7.commonsitext7.font-asian(后者用于处理亚洲字体,如中文)。
    • 注意​:对于商业项目,请务必查看 iText 的 AGPL 许可证或购买商业许可证。对于学习和小型内部项目,AGPL 通常是起点。

第二步:核心概念与初始化

在开始编码前,了解两个核心类:

  • PdfWriter: 负责将 PDF 内容写入到文件流或内存流中。
  • PdfDocument: 代表 PDF 文档本身,是所有页面和元素的容器。
  • Document: 一个高级抽象,它使用 PdfDocument 并向其中添加段落、图像等内容。它极大地简化了布局操作。

我们将使用 PdfWriterDocument 类来创建和操作 PDF。


第三步:完整代码示例与分步解析

下面是一个完整的 C# 程序,演示了如何创建一个包含文本、图片、形状和表格的 PDF 文档。

using System.IO;
using iText.IO.Image;
using iText.Kernel.Colors;
using iText.Kernel.Font;
using itext.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;

namespace CreatePdfTutorial
{
    class Program
    {
        static void Main(string[] args)
        {
            // 1. 定义输出文件路径
            string outputPath = @"C:\temp\MyFirstPdf.pdf"; // 请确保此路径存在,或修改为你想要的路径

            // 2. 创建 PdfWriter 和 PdfDocument
            // using 语句确保资源被正确释放
            using (FileStream stream = new FileStream(outputPath, FileMode.Create))
            {
                PdfWriter writer = new PdfWriter(stream);
                PdfDocument pdfDoc = new PdfDocument(writer);
                
                // 3. 创建 Document 对象,它是我们的主要操作入口
                // 使用默认页面大小 (A4)
                Document document = new Document(pdfDoc);

                // 可选:注册中文字体,防止中文显示为乱码或空白
                // 你需要将字体文件(如 simhei.ttf)放在项目目录中并设置“如果较新则复制”
                // string fontPath = Path.Combine(Directory.GetCurrentDirectory(), "simhei.ttf");
                // PdfFont chineseFont = PdfFontFactory.CreateFont(fontPath, PdfEncodings.IDENTITY_H, PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED);
                // 为了简化,本示例使用默认字体,可能无法显示中文。

                // 4. 添加内容
                AddContentToDocument(document);

                // 5. 关闭 Document,这将把所有内容写入 PdfDocument 并关闭文件流
                document.Close();
            }

            Console.WriteLine($"PDF 创建成功!路径:{outputPath}");
        }

        static void AddContentToDocument(Document document)
        {
            // --- 插入标题文本 ---
            Paragraph title = new Paragraph("C# 创建 PDF 综合示例")
                .SetTextAlignment(TextAlignment.CENTER)
                .SetFontSize(24)
                .SetBold()
                .SetMarginBottom(20);
            document.Add(title);

            // --- 插入普通文本段落 ---
            Paragraph paragraph = new Paragraph("这是一个使用 iText 7 创建的 PDF 文档示例。我们可以看到,它可以轻松地添加各种元素。")
                .SetFontSize(12)
                .SetMarginBottom(15);
            document.Add(paragraph);

            // --- 插入图片 ---
            try
            {
                // 图片路径,请替换为你的图片文件
                string imagePath = @"C:\path\to\your\image.jpg"; // 例如:@"C:\temp\logo.png"
                ImageData imageData = ImageDataFactory.Create(imagePath);
                Image image = new Image(imageData)
                    .SetWidth(200) // 设置图片宽度,高度会按比例缩放
                    .SetHorizontalAlignment(HorizontalAlignment.CENTER) // 居中
                    .SetMarginTop(10)
                    .SetMarginBottom(20);
                document.Add(image);
            }
            catch (System.IO.IOException e)
            {
                // 如果图片找不到,添加一个占位文本
                document.Add(new Paragraph("[图片加载失败,请检查路径]").SetFontColor(ColorConstants.RED));
            }


            // --- 插入形状 (通过绘制线条和矩形) ---
            // iText 没有直接“形状”对象,但可以通过 'Canvas' 在特定位置绘制
            // 我们先添加一个标题
            document.Add(new Paragraph("绘制的形状示例:").SetFontSize(14).SetBold().SetMarginTop(20));

            // 获取当前页面的尺寸
            Rectangle pageSize = document.GetPdfDocument().GetDefaultPageSize();
            
            // 创建一个 Canvas 对象,它允许我们在绝对位置上绘图
            // 参数:PdfPage, 矩形区域(这里我们传入页面边界,但实际绘图在 margin 内)
            // 我们创建一个位于内容区的 Canvas
            float x = pageSize.GetLeft() + 36; // 左边距
            float y = pageSize.GetTop() - 150; // 从上往下150点
            float width = pageSize.GetWidth() - 72; // 可用宽度 (减去左右边距)
            float height = 100; // 高度
            
            // 在指定位置添加一个带边框的矩形
            DrawRectangle(document, x, y, width, height, ColorConstants.BLUE, 2f);

            // 在矩形内画一条对角线
            PdfCanvas pdfCanvas = new PdfCanvas(document.GetPdfDocument().GetLastPage());
            pdfCanvas
                .SaveState()
                .SetStrokeColor(ColorConstants.RED)
                .SetLineWidth(3f)
                .MoveTo(x, y) // 起点:矩形左上角
                .LineTo(x + width, y - height) // 终点:矩形右下角
                .Stroke()
                .RestoreState();


            // --- 插入表格 ---
            document.Add(new Paragraph("员工信息表:").SetFontSize(14).SetBold().SetMarginTop(30));

            // 1. 创建表格对象,参数是列数
            Table table = new Table(3); // 创建一个 3 列的表格
            table.SetWidth(UnitValue.CreatePercentValue(100)); // 设置表格宽度为页面宽度的100%
            table.SetMarginTop(10);

            // 2. 添加表头
            Cell headerCell1 = new Cell().Add(new Paragraph("姓名")).SetBackgroundColor(ColorConstants.LIGHT_GRAY).SetBold();
            Cell headerCell2 = new Cell().Add(new Paragraph("部门")).SetBackgroundColor(ColorConstants.LIGHT_GRAY).SetBold();
            Cell headerCell3 = new Cell().Add(new Paragraph("入职年份")).SetBackgroundColor(ColorConstants.LIGHT_GRAY).SetBold();
            
            table.AddHeaderCell(headerCell1);
            table.AddHeaderCell(headerCell2);
            table.AddHeaderCell(headerCell3);

            // 3. 添加数据行
            table.AddCell(new Cell().Add(new Paragraph("张三")));
            table.AddCell(new Cell().Add(new Paragraph("技术部")));
            table.AddCell(new Cell().Add(new Paragraph("2020")));

            table.AddCell("李四"); // Cell 也接受字符串直接构造
            table.AddCell("市场部");
            table.AddCell("2021");

            table.AddCell("王五");
            table.AddCell("人力资源部");
            table.AddCell("2019");

            // 4. 将表格添加到文档
            document.Add(table);
        }

        /// <summary>
        /// 辅助方法:在指定位置绘制一个带边框的矩形
        /// </summary>
        static void DrawRectangle(Document doc, float x, float y, float width, float height, Color color, float lineWidth)
        {
            PdfCanvas canvas = new PdfCanvas(doc.GetPdfDocument().GetLastPage());
            canvas.SaveState()
                  .SetStrokeColor(color)
                  .SetLineWidth(lineWidth)
                  .Rectangle(x, y - height, width, height) // iText 的坐标系 Y 轴向下为正,所以高度为负
                  .Stroke()
                  .RestoreState();
        }
    }
}

第四步:代码分步解析

  1. 初始化与文件流: using (FileStream stream = new FileStream(outputPath, FileMode.Create)) { PdfWriter writer = new PdfWriter(stream); PdfDocument pdfDoc = new PdfDocument(writer); Document document = new Document(pdfDoc); // ... 添加内容 document.Close(); } 这是标准的创建流程。using 块确保文件流和 PDF 文档被正确关闭和释放。
  2. 添加文本:
    • Paragraph 是主要的文本块容器。
    • 使用 SetTextAlignment, SetFontSize, SetBold 等方法可以轻松格式化文本。
  3. 添加图片:
    • 使用 ImageDataFactory.Create(path) 加载图片。
    • 创建 Image 对象并设置其大小和对齐方式。
    • 务必添加错误处理,以防图片路径错误或文件损坏。
  4. 插入形状:
    • iText 没有直接的“形状”API。我们通过 PdfCanvas 在绝对坐标上进行绘制。
    • DrawRectangle 辅助方法演示了如何绘制一个有边框的矩形。
    • 画直线使用了 pdfCanvas.MoveTo()LineTo() 方法。
    • 注意坐标系​:PDF 的坐标原点 (0,0) 通常在页面左下角,Y 轴向上为正。但 Document 的布局逻辑会处理大部分偏移,我们在 Canvas 上绘图时需要小心计算坐标。
  5. 插入表格:
    • 创建 Table 对象时指定列数。
    • table.SetWidth(UnitValue.CreatePercentValue(100)) 让表格自适应页面宽度,这是个好习惯。
    • 使用 AddHeaderCell() 添加表头,并用 SetBackgroundColor 美化。
    • 使用 AddCell() 添加数据行,可以直接传字符串或 Cell 对象以获得更多控制。

第五步:运行与故障排除

  1. 运行​:编译并运行程序。如果一切顺利,你会在 C:\temp\(或你指定的路径)找到一个名为 MyFirstPdf.pdf 的文件。
  2. 常见问题:
    • 中文乱码/空白​:这是最常见的问题。你必须嵌入一个支持中文的字体(如 SimHei, Microsoft YaHei)。取消代码中注册字体的注释,并下载相应的 .ttf 文件。
    • 文件无法创建​:检查输出路径是否存在且有写入权限。
    • 图片不显示​:检查图片路径是否正确,格式是否被支持(JPG, PNG, GIF 等)。
    • NuGet 包错误​:确保安装的 iText7 包版本兼容,并尝试清理和重建解决方案。

这个教程提供了一个坚实的基础,你可以在此基础上探索 iText 7 更强大的功能,如列表、链接、列表、PDF 表单、加密等。查阅 iText 7 官方文档 是深入学习的最佳途径。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞30 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容