标签 C# 下的文章

在现代软件开发中,生成文档自动化变得越来越重要。借助像 Spire.Doc for .NET 这样的库,我们可以轻松地在 C# 中创建和操作 Word 文档。本文将介绍如何使用 Spire.Doc 创建一个简单的 Word 文档,涉及到标题、段落等文本元素的添加。

Spire.Doc for .NET 简介

Spire.Doc 是一款功能强大的 .NET 文档处理组件,它允许开发者在 C# 和 VB.NET 中创建、读取、编辑和保存 Word 文档。该库支持多种格式,包括 DOC、DOCX、HTML 和 PDF。用户可以简单地通过代码来控制文档的内容和样式,进而生成满足需求的文档。

NuGet 安装

要在项目中使用 Spire.Doc,你可以通过 NuGet 包管理器轻松安装。只需在命令行中输入以下命令:

Install-Package Spire.Doc

安装完成后,你就可以开始使用 Spire.Doc 创建 Word 文档了。

示例代码

下面的代码示例展示了如何使用 C# 和 Spire.Doc 创建一个包含标题和段落的简单 Word 文档。

using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System.Drawing;

namespace CreateSimpleWordDocument
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建Document对象
            Document document = new Document();

            // 添加节
            Section section = document.AddSection();

            // 设置页边距
            section.PageSetup.Margins.All = 60f;

            // 添加一个标题段落
            Paragraph title_para = section.AddParagraph();
            TextRange textRange = title_para.AppendText("这是标题");
            title_para.ApplyStyle(BuiltinStyle.Title);
            textRange.CharacterFormat.FontName = "宋体";

            // 添加几个小标题段落
            string[] headings = { "这是标题1", "这是标题2", "这是标题3", "这是标题4" };
            for (int i = 0; i < headings.Length; i++)
            {
                Paragraph heading = section.AddParagraph();
                textRange = heading.AppendText(headings[i]);
                heading.ApplyStyle((BuiltinStyle)((int)BuiltinStyle.Heading1 + i));
                textRange.CharacterFormat.FontName = "宋体";
            }

            // 添加一个段落
            Paragraph normal_para = section.AddParagraph();
            normal_para.AppendText("这是一个段落。");

            // 创建段落样式
            ParagraphStyle style = new ParagraphStyle(document);
            style.Name = "paraStyle";
            style.CharacterFormat.FontName = "宋体";
            style.CharacterFormat.FontSize = 13f;
            style.CharacterFormat.TextColor = Color.Brown;
            document.Styles.Add(style);

            // 将自定义样式应用到指定段落
            normal_para.ApplyStyle("paraStyle");

            // 保存文档
            document.SaveToFile("AddText.docx", FileFormat.Docx);

            // 释放资源
            document.Dispose();
        }
    }
}

代码详解

  1. 创建 Document 对象 :首先,我们实例化一个 Document 对象,这是文档的核心。
  2. 添加节 :使用 AddSection() 方法,我们可以向文档添加新的节。
  3. 设置页面边距 :使用 PageSetup.Margins 属性可以轻松设置页边距。
  4. 添加标题和段落

    • 我们可以通过 AddParagraph() 方法添加段落,并利用 AppendText() 方法添加文本。
    • Spire.Doc 允许使用内置样式,通过 ApplyStyle() 方法为段落应用不同的样式。
  5. 自定义段落样式 :使用 ParagraphStyle 类,我们可以定义自己的段落样式并应用到段落上。
  6. 保存文档 :最后,我们使用 SaveToFile() 方法将文档保存为 .docx 格式。

更多功能

如果想要了解如何在 Word 文档中添加图片、列表等更复杂的元素,可以参考 Spire.Doc 的在线教程。这些教程涵盖了库的更多先进功能,帮助你更好地掌握文档生成的技术。

结论

通过本文的介绍,你应该能够使用 C# 和 Spire.Doc 创建一个包含基本元素的 Word 文档。无论是生成报告、合同或其他任何文档,Spire.Doc 都提供了丰富的功能,满足各种需求。继续探索更多特性,你将能创建出更加复杂和专业的文档。

在日常企业办公和数据分析中,表格数据的可视化和文档化非常常见。无论是产品销售报表、库存清单,还是项目进度表,通常都会希望将数据直接导出为 Word 文档,以便打印、归档或分发。手动复制粘贴不仅效率低,而且容易出错。借助 C#,我们可以轻松将 DataTable 数据生成格式规范、可自定义样式的 Word 表格,实现自动化办公。

本文将带你完整了解从创建 Word 文档、构建表格、填充数据到保存文档的流程,并重点讲解核心技术细节和关键 API 使用方式。

文中使用的方法需要用到 Free Spire.Doc for .NET,可通过 NuGet 安装:dotnet add package FreeSpire.Doc


核心流程与实现

导出 DataTable 到 Word 文档的流程主要包括以下几个步骤:

  1. 创建 Word 文档对象及章节
  2. 添加文档标题
  3. 校验 DataTable 数据
  4. 构建 Word 表格并设置样式
  5. 填充表头与数据
  6. 保存文档

下面给出完整示例代码(已优化结构和示例数据):

using System;
using System.Data;
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System.Drawing;

public class DataTableToWordExporter
{
    public static void ExportDataTableToWord(DataTable dataTable, string filePath)
    {
        // 1. 创建 Word 文档
        Document document = new Document();
        Section section = document.AddSection();

        // 2. 添加文档标题
        Paragraph titlePara = section.AddParagraph();
        titlePara.Format.HorizontalAlignment = HorizontalAlignment.Center;
        TextRange titleText = titlePara.AppendText("月度产品库存报表");
        titleText.CharacterFormat.FontSize = 20;
        titleText.CharacterFormat.Bold = true;

        // 添加空行
        section.AddParagraph().AppendText(Environment.NewLine);

        // 3. 校验 DataTable 数据
        if (dataTable == null || dataTable.Rows.Count == 0)
        {
            section.AddParagraph().AppendText("当前没有可用数据。");
            document.SaveToFile(filePath, FileFormat.Docx);
            Console.WriteLine("数据为空,文档已保存。");
            return;
        }

        // 4. 创建 Word 表格
        Table table = section.AddTable(true);
        table.ResetCells(dataTable.Rows.Count + 1, dataTable.Columns.Count);

        // 设置表格整体样式
        table.TableFormat.Borders.LineWidth = 1;
        table.TableFormat.Borders.BorderType = BorderStyle.Single;
        table.TableFormat.Borders.Color = Color.Black;
        table.PreferredWidth = new PreferredWidth(WidthType.Percentage, 100);
        table.TableFormat.HorizontalAlignment = RowAlignment.Center;

        // 5. 填充表头
        TableRow headerRow = table.Rows[0];
        headerRow.IsHeader = true;
        headerRow.RowFormat.BackColor = Color.LightGray;
        headerRow.RowFormat.Height = 25;
        headerRow.RowFormat.HeightType = TableRowHeightType.Exactly;

        for (int i = 0; i < dataTable.Columns.Count; i++)
        {
            headerRow.Cells[i].CellFormat.VerticalAlignment = VerticalAlignment.Middle;
            Paragraph p = headerRow.Cells[i].AddParagraph();
            p.Format.HorizontalAlignment = HorizontalAlignment.Center;
            TextRange tr = p.AppendText(dataTable.Columns[i].ColumnName);
            tr.CharacterFormat.Bold = true;
            tr.CharacterFormat.FontSize = 11;
        }

        // 6. 填充数据行
        for (int r = 0; r < dataTable.Rows.Count; r++)
        {
            TableRow dataRow = table.Rows[r + 1];
            dataRow.RowFormat.Height = 20;
            dataRow.RowFormat.HeightType = TableRowHeightType.Exactly;

            for (int c = 0; c < dataTable.Columns.Count; c++)
            {
                dataRow.Cells[c].CellFormat.VerticalAlignment = VerticalAlignment.Middle;
                Paragraph p = dataRow.Cells[c].AddParagraph();
                p.Format.HorizontalAlignment = HorizontalAlignment.Center;
                TextRange tr = p.AppendText(dataTable.Rows[r][c].ToString());
                tr.CharacterFormat.FontSize = 10;
            }
        }

        // 7. 保存文档
        try
        {
            document.SaveToFile(filePath, FileFormat.Docx);
            Console.WriteLine($"DataTable 已成功导出到 Word 文档:{filePath}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"导出 Word 文档时发生错误:{ex.Message}");
        }
    }

    public static void Main()
    {
        // 模拟 DataTable 数据
        DataTable dt = new DataTable("Products");
        dt.Columns.Add("产品ID", typeof(int));
        dt.Columns.Add("产品名称", typeof(string));
        dt.Columns.Add("类别", typeof(string));
        dt.Columns.Add("单价", typeof(decimal));
        dt.Columns.Add("库存量", typeof(int));

        dt.Rows.Add(201, "激光打印机", "办公设备", 3200.00m, 25);
        dt.Rows.Add(202, "办公桌椅套装", "家具", 1800.00m, 15);
        dt.Rows.Add(203, "液晶显示器", "显示设备", 1500.00m, 40);
        dt.Rows.Add(204, "无线键鼠套装", "外设", 250.00m, 100);
        dt.Rows.Add(205, "移动硬盘", "存储设备", 480.00m, 60);

        string outputPath = "ProductInventoryReport.docx";
        ExportDataTableToWord(dt, outputPath);

        // 测试空数据情况
        DataTable emptyDt = new DataTable("Empty");
        emptyDt.Columns.Add("ID");
        ExportDataTableToWord(emptyDt, "EmptyReport.docx");
    }
}

以下是上面代码生成的Word文档:

C#导出DataTable到Word结果文档


核心技术解析

在这个示例中,最关键的技术点如下:

  1. Word 文档对象与章节
    Document document = new Document();
    Section section = document.AddSection();
    使用 Document 对象创建新文档,Section 提供页布局和内容容器。
  2. 表格创建与单元格操作
    Table table = section.AddTable(true);
    table.ResetCells(rows, columns);
    表格的行列数量与 DataTable 对应,单元格填充通过 AddParagraph() + AppendText() 实现。
  3. 表头样式设置
    通过 RowFormat.BackColorRowFormat.HeightTextRange.CharacterFormat 设置字体加粗、字号和单元格背景色,使表格专业美观。
  4. 数据填充与居中对齐
    利用循环遍历 DataTable.RowsDataTable.Columns,将数据逐行写入 Word 单元格,并使用 HorizontalAlignment.CenterVerticalAlignment.Middle 保持表格整齐。
  5. 空数据处理
    在 DataTable 无数据时提供提示并仍保存文档,保证程序稳健性。

核心 API 总结

类 / 属性 / 方法说明
DocumentWord 文档对象,可添加 Section、表格、段落等
Section文档章节容器,承载段落和表格
Section.AddParagraph()添加段落
Section.AddTable(bool)添加表格,参数表示是否自动适应页面宽度
Table.ResetCells(rows, cols)重置表格行列数量
TableRow表格行对象,可设置高度、背景色
TableRow.Cells单元格集合
Paragraph段落对象,可添加文本
Paragraph.AppendText(string)向段落添加文本
TextRange.CharacterFormat设置字体、字号、加粗等文本样式
CellFormat单元格格式,包括垂直对齐等
HorizontalAlignment / VerticalAlignment文本水平/垂直对齐方式
Document.SaveToFile()保存文档,支持 DOCX、PDF 等格式

总结

本文展示了如何使用 C#DataTable 数据导出为 Word 文档,实现表格化展示与自动排版。通过 Spire.Doc,你不仅可以轻松创建文档和章节,还能自动生成格式规范的表格,同时处理空数据情况,保证程序运行的稳健性。在表头样式和数据对齐的控制下,导出的文档既美观又易于阅读。掌握这些技术后,你可以将数据库或 Excel 中的业务数据快速转换为 Word 报表,大幅减少手动操作的时间,同时在企业报表自动化、数据归档和文档生成等场景中提升工作效率和专业性。

更多 Word 文档处理技巧请前往 Spire.Doc 文档中心查看。

在日常企业办公和数据分析中,表格数据的可视化和文档化非常常见。无论是产品销售报表、库存清单,还是项目进度表,通常都会希望将数据直接导出为 Word 文档,以便打印、归档或分发。手动复制粘贴不仅效率低,而且容易出错。借助 C#,我们可以轻松将 DataTable 数据生成格式规范、可自定义样式的 Word 表格,实现自动化办公。

本文将带你完整了解从创建 Word 文档、构建表格、填充数据到保存文档的流程,并重点讲解核心技术细节和关键 API 使用方式。

文中使用的方法需要用到 Free Spire.Doc for .NET,可通过 NuGet 安装:dotnet add package FreeSpire.Doc


核心流程与实现

导出 DataTable 到 Word 文档的流程主要包括以下几个步骤:

  1. 创建 Word 文档对象及章节
  2. 添加文档标题
  3. 校验 DataTable 数据
  4. 构建 Word 表格并设置样式
  5. 填充表头与数据
  6. 保存文档

下面给出完整示例代码(已优化结构和示例数据):

using System;
using System.Data;
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System.Drawing;

public class DataTableToWordExporter
{
    public static void ExportDataTableToWord(DataTable dataTable, string filePath)
    {
        // 1. 创建 Word 文档
        Document document = new Document();
        Section section = document.AddSection();

        // 2. 添加文档标题
        Paragraph titlePara = section.AddParagraph();
        titlePara.Format.HorizontalAlignment = HorizontalAlignment.Center;
        TextRange titleText = titlePara.AppendText("月度产品库存报表");
        titleText.CharacterFormat.FontSize = 20;
        titleText.CharacterFormat.Bold = true;

        // 添加空行
        section.AddParagraph().AppendText(Environment.NewLine);

        // 3. 校验 DataTable 数据
        if (dataTable == null || dataTable.Rows.Count == 0)
        {
            section.AddParagraph().AppendText("当前没有可用数据。");
            document.SaveToFile(filePath, FileFormat.Docx);
            Console.WriteLine("数据为空,文档已保存。");
            return;
        }

        // 4. 创建 Word 表格
        Table table = section.AddTable(true);
        table.ResetCells(dataTable.Rows.Count + 1, dataTable.Columns.Count);

        // 设置表格整体样式
        table.TableFormat.Borders.LineWidth = 1;
        table.TableFormat.Borders.BorderType = BorderStyle.Single;
        table.TableFormat.Borders.Color = Color.Black;
        table.PreferredWidth = new PreferredWidth(WidthType.Percentage, 100);
        table.TableFormat.HorizontalAlignment = RowAlignment.Center;

        // 5. 填充表头
        TableRow headerRow = table.Rows[0];
        headerRow.IsHeader = true;
        headerRow.RowFormat.BackColor = Color.LightGray;
        headerRow.RowFormat.Height = 25;
        headerRow.RowFormat.HeightType = TableRowHeightType.Exactly;

        for (int i = 0; i < dataTable.Columns.Count; i++)
        {
            headerRow.Cells[i].CellFormat.VerticalAlignment = VerticalAlignment.Middle;
            Paragraph p = headerRow.Cells[i].AddParagraph();
            p.Format.HorizontalAlignment = HorizontalAlignment.Center;
            TextRange tr = p.AppendText(dataTable.Columns[i].ColumnName);
            tr.CharacterFormat.Bold = true;
            tr.CharacterFormat.FontSize = 11;
        }

        // 6. 填充数据行
        for (int r = 0; r < dataTable.Rows.Count; r++)
        {
            TableRow dataRow = table.Rows[r + 1];
            dataRow.RowFormat.Height = 20;
            dataRow.RowFormat.HeightType = TableRowHeightType.Exactly;

            for (int c = 0; c < dataTable.Columns.Count; c++)
            {
                dataRow.Cells[c].CellFormat.VerticalAlignment = VerticalAlignment.Middle;
                Paragraph p = dataRow.Cells[c].AddParagraph();
                p.Format.HorizontalAlignment = HorizontalAlignment.Center;
                TextRange tr = p.AppendText(dataTable.Rows[r][c].ToString());
                tr.CharacterFormat.FontSize = 10;
            }
        }

        // 7. 保存文档
        try
        {
            document.SaveToFile(filePath, FileFormat.Docx);
            Console.WriteLine($"DataTable 已成功导出到 Word 文档:{filePath}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"导出 Word 文档时发生错误:{ex.Message}");
        }
    }

    public static void Main()
    {
        // 模拟 DataTable 数据
        DataTable dt = new DataTable("Products");
        dt.Columns.Add("产品ID", typeof(int));
        dt.Columns.Add("产品名称", typeof(string));
        dt.Columns.Add("类别", typeof(string));
        dt.Columns.Add("单价", typeof(decimal));
        dt.Columns.Add("库存量", typeof(int));

        dt.Rows.Add(201, "激光打印机", "办公设备", 3200.00m, 25);
        dt.Rows.Add(202, "办公桌椅套装", "家具", 1800.00m, 15);
        dt.Rows.Add(203, "液晶显示器", "显示设备", 1500.00m, 40);
        dt.Rows.Add(204, "无线键鼠套装", "外设", 250.00m, 100);
        dt.Rows.Add(205, "移动硬盘", "存储设备", 480.00m, 60);

        string outputPath = "ProductInventoryReport.docx";
        ExportDataTableToWord(dt, outputPath);

        // 测试空数据情况
        DataTable emptyDt = new DataTable("Empty");
        emptyDt.Columns.Add("ID");
        ExportDataTableToWord(emptyDt, "EmptyReport.docx");
    }
}

以下是上面代码生成的Word文档:

C#导出DataTable到Word结果文档


核心技术解析

在这个示例中,最关键的技术点如下:

  1. Word 文档对象与章节
    Document document = new Document();
    Section section = document.AddSection();
    使用 Document 对象创建新文档,Section 提供页布局和内容容器。
  2. 表格创建与单元格操作
    Table table = section.AddTable(true);
    table.ResetCells(rows, columns);
    表格的行列数量与 DataTable 对应,单元格填充通过 AddParagraph() + AppendText() 实现。
  3. 表头样式设置
    通过 RowFormat.BackColorRowFormat.HeightTextRange.CharacterFormat 设置字体加粗、字号和单元格背景色,使表格专业美观。
  4. 数据填充与居中对齐
    利用循环遍历 DataTable.RowsDataTable.Columns,将数据逐行写入 Word 单元格,并使用 HorizontalAlignment.CenterVerticalAlignment.Middle 保持表格整齐。
  5. 空数据处理
    在 DataTable 无数据时提供提示并仍保存文档,保证程序稳健性。

核心 API 总结

类 / 属性 / 方法说明
DocumentWord 文档对象,可添加 Section、表格、段落等
Section文档章节容器,承载段落和表格
Section.AddParagraph()添加段落
Section.AddTable(bool)添加表格,参数表示是否自动适应页面宽度
Table.ResetCells(rows, cols)重置表格行列数量
TableRow表格行对象,可设置高度、背景色
TableRow.Cells单元格集合
Paragraph段落对象,可添加文本
Paragraph.AppendText(string)向段落添加文本
TextRange.CharacterFormat设置字体、字号、加粗等文本样式
CellFormat单元格格式,包括垂直对齐等
HorizontalAlignment / VerticalAlignment文本水平/垂直对齐方式
Document.SaveToFile()保存文档,支持 DOCX、PDF 等格式

总结

本文展示了如何使用 C#DataTable 数据导出为 Word 文档,实现表格化展示与自动排版。通过 Spire.Doc,你不仅可以轻松创建文档和章节,还能自动生成格式规范的表格,同时处理空数据情况,保证程序运行的稳健性。在表头样式和数据对齐的控制下,导出的文档既美观又易于阅读。掌握这些技术后,你可以将数据库或 Excel 中的业务数据快速转换为 Word 报表,大幅减少手动操作的时间,同时在企业报表自动化、数据归档和文档生成等场景中提升工作效率和专业性。

更多 Word 文档处理技巧请前往 Spire.Doc 文档中心查看。

在企业日常办公和文档管理中,PDF 已经成为最常用的电子文档格式。无论是财务报表、项目计划,还是合同协议,PDF 都能保证内容在不同平台下的统一显示。然而,当文档页数增加时,页码的缺失或混乱会影响文档的可读性和专业性。

手动为每页添加页码不仅耗时,而且容易出错。对于开发者来说,利用 C# 可以在 .NET 项目中实现自动化页码插入,从而显著提高工作效率,同时保证页码的准确性和格式统一。本文将带你从基础操作到高级定制,完整掌握 PDF 页码自动化的方法。

本文所使用的方法需要用到Free Spire.PDF for .NET,可通过 NuGet 安装:dotnet add package FreeSpire.PDF


2. 加载 PDF 并获取页面信息

在插入页码之前,需要先加载已有的 PDF 文档,并获取页面数量:

using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;

string inputFile = "ExistingDocument.pdf";
string outputFile = "DocumentWithPageNumbers.pdf";

// 加载 PDF 文档
PdfDocument doc = new PdfDocument();
doc.LoadFromFile(inputFile);

// 获取总页数
int pageCount = doc.Pages.Count;

在这个阶段,我们已经能够访问文档的每一页,为后续插入页码做准备。


3. 基础页码插入

最简单的页码样式是“第 X 页”,插入到页面底部居中:

for (int i = 0; i < pageCount; i++)
{
    PdfPageBase page = doc.Pages[i];

    PdfFont font = new PdfTrueTypeFont(new Font("宋体", 10f));
    PdfBrush brush = PdfBrushes.Black;

    string pageNumberText = $"第{i + 1}页";

    SizeF textSize = font.MeasureString(pageNumberText);
    float x = (page.Canvas.ClientSize.Width - textSize.Width) / 2;
    float y = page.Canvas.ClientSize.Height - textSize.Height - 10;

    page.Canvas.DrawString(pageNumberText, font, brush, x, y);
}

关键点解析

  • PdfTrueTypeFont 用于设置字体类型和大小
  • MeasureString 用于计算文本宽度,以便实现居中对齐
  • 坐标 (x, y) 控制页码在页面上的精确位置

4. 保存文档

完成页码插入后,记得保存文件并释放资源:

doc.SaveToFile(outputFile);
doc.Close();

经过以上步骤,已有 PDF 文档就成功生成了专业的页码,无需手动操作 PDF 文档。

以下是生成的 PDF 页码效果预览:

C#生成PDF页码


5 页码高级应用与优化策略

自定义页码格式

企业文档通常要求显示“第 X 页,共 Y 页”,或者英文的“Page X of Y”。只需在字符串中格式化即可:

string pageNumberText = $"第{i + 1}页,共{pageCount}页";
// 或者英文格式
// string pageNumberText = $"Page {i + 1} of {pageCount}";

这样可以保证文档在打印或归档时,页码信息清晰且专业。

灵活控制页码位置

页码不仅可以放在底部居中,还可以放在页脚左侧、右侧,甚至页眉区域。通过调整 X、Y 坐标即可实现不同布局:

// 页脚右侧
float xRight = page.Canvas.ClientSize.Width - textSize.Width - 20;
float yBottom = page.Canvas.ClientSize.Height - textSize.Height - 20;
page.Canvas.DrawString(pageNumberText, font, brush, xRight, yBottom);

// 页眉居中
float xTop = (page.Canvas.ClientSize.Width - textSize.Width) / 2;
float yTop = 10;
page.Canvas.DrawString(pageNumberText, font, brush, xTop, yTop);

排除首页或指定页开始

在报告或合同中,封面页通常不显示页码,或页码从第二页开始:

for (int i = 0; i < pageCount; i++)
{
    if (i == 0) continue; // 跳过首页

    PdfPageBase page = doc.Pages[i];
    string pageNumberText = $"第{i}页,共{pageCount - 1}页";
    SizeF textSize = font.MeasureString(pageNumberText);
    float x = (page.Canvas.ClientSize.Width - textSize.Width) / 2;
    float y = page.Canvas.ClientSize.Height - textSize.Height - 15;

    page.Canvas.DrawString(pageNumberText, font, brush, x, y);
}

这样可以灵活应对各种文档排版需求。

更多页码样式设置

页码的字体、字号、颜色可以根据企业品牌或文档风格进行自定义:

PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial", 12f, FontStyle.Bold | FontStyle.Italic));
PdfBrush brush = new PdfSolidBrush(Color.DarkBlue);

结合坐标计算,可以在页面左、中、右随意放置页码,同时保证样式统一。


总结

通过本文的示例,C# 开发者可以轻松为已有 PDF 文档自动添加页码,无需手动操作。代码不仅适用于单页文档,也能处理多页 PDF,并提供了页码样式和位置的灵活控制。这种方法极大提升了办公效率,保证了文档的专业性和规范性,同时也为批量文档处理提供了可靠的技术方案。掌握这一技巧,你可以在财务报表、项目文档、合同协议等各类 PDF 文件中快速生成标准化页码,使文档既清晰又美观。

更多 PDF 文档操作技巧,请前往 Spire.PDF 文档中心查看。

[软件推荐] AllLive (C# 版) + Simple Live:打造全平台直播观看双保险

大家好,之前论坛里也有不少朋友推荐过 Simple Live,它确实是一款非常优秀的开源全平台直播聚合工具。

今天我想特别介绍一下同一位作者(逍遥橙子)的另一个项目:AllLive。虽然两者功能相似,但它们的底层实现不同(Simple Live 是 Flutter,AllLive 是 C#),且在不同场景下各有优势。

为什么选择 AllLive?

  1. 多端支持:AllLive 是基于 C# 开发的,拥有 Windows 客户端,并且已上架 Microsoft Store,安装和更新非常方便。
  2. 试用友好:软件提供永久免费的试用版(付费版仅用于支持作者,功能完全一致)。
  3. 数据同步:虽然 Simple Live 早就支持多设备同步和 WebDAV 备份,但 AllLive 在 Windows 端的表现更加原生流畅。

我的使用场景与解决方案

平时我喜欢看 B 站 和 抖音 的唱歌主播:

  • B 站:两者适配都很完美。
  • 抖音:这里有个小痛点,AllLive 的搜索功能在抖音上目前是失效的

我的 “骚操作”:
利用 Simple Live 强大的链接解析能力来 “助攻” AllLive。

  1. 在手机端(Simple Live)中打开抖音直播间,复制链接。
  2. 在电脑端(AllLive)中通过链接解析进入直播间。
  3. 关注该主播,这样数据就会同步到 AllLive 的电脑端,方便后续观看。

总结

如果你更喜欢 Windows 原生应用,或者想体验 C# 实现的流畅度,AllLive 是个不错的选择。
配合 Simple Live 解析链接,两者互补,体验极佳。


界面预览

图一:在 Simple Live 中解析抖音链接并关注主播

图二:数据同步后,在 AllLive (Windows) 端的观看界面


📌 转载信息
原作者:
kerokero
转载时间:
2026/1/21 22:39:31

在当今数字化的世界中,PDF(便携式文档格式)已成为文档分享和打印的标准格式。作为开发者,能够通过代码操作和打印 PDF 文档是非常实用的。本文将介绍如何使用 Spire.PDF for .NET 库打印 PDF 文档,详细说明安装步骤以及代码解析,帮助您快速上手。

Spire.PDF for .NET 简介

Spire.PDF for .NET 是一个功能丰富的 PDF 处理库,它使开发者可以在 C# 应用程序中创建、修改和打印 PDF 文件。该库不仅支持基本的 PDF 操作,还提供许多高级功能,如文本和图像提取、PDF 文件合并和安全性设置等。

主要特性

  • 创建和编辑 PDF :支持创建新的 PDF 文档和对现有文档进行编辑。
  • 打印功能 :能够打印 PDF 文档到默认或指定打印机,灵活便捷。
  • 文件转换 :能够将 PDF 文件转换为 Word、Excel 等格式,方便后续的编辑。
  • 安全性 :支持对 PDF 文件进行加密、解密和密码设置,确保文档安全。

安装 Spire.PDF for .NET

要在项目中使用 Spire.PDF,您需要先将其安装。安装的方法有以下两种:

  1. 使用 NuGet 安装

    • 打开 Visual Studio,点击“工具”->“NuGet 包管理器”->“包管理器控制台”。
    • 输入以下命令并运行:

      Install-Package Spire.PDF
  2. 使用 Visual Studio GUI

    • 在解决方案资源管理器中右键点击您的项目,选择“管理 NuGet 包”。
    • 在搜索框中输入“Spire.PDF”,找到并点击安装相关包。

这两种方法都可以将 Spire.PDF 库添加到您的项目中,便于后续使用。

打印 PDF 文档的代码示例

以下是一个简单的 C# 控制台应用程序示例,展示如何打印 PDF 文档:

using Spire.Pdf;

namespace PrintWithDefaultPrinter
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个 PdfDocument 对象
            PdfDocument doc = new PdfDocument();

            // 加载 PDF 文件
            doc.LoadFromFile("C:/Users/Administrator/Desktop/Input.pdf");

            // 设置打印机名称
            doc.PrintSettings.PrinterName = "Your Printer Name";

            // 设置打印页面范围
            doc.PrintSettings.SelectPageRange(1, 5); // 打印第 1 到第 5 页

            // 设置打印份数
            doc.PrintSettings.Copies = 2;

            // 设置为黑白打印
            doc.PrintSettings.Color = false;

            // 检查打印机是否支持双面打印
            if (doc.PrintSettings.CanDuplex)
            {
                doc.PrintSettings.Duplex = Duplex.Default; // 设置为默认双面打印
            }

            // 打印到默认打印机
            doc.Print();

            // 清理资源
            doc.Dispose();
        }
    }
}

代码解析

  • 创建 PdfDocument 对象 :初始化一个新的 PdfDocument 对象,用于加载和操作 PDF 文件。
  • 加载 PDF 文件 :通过 LoadFromFile 方法加载指定路径的 PDF 文件。请确保文件路径正确且文件存在。
  • 设置打印机名称 :使用 PrinterName 属性指定打印机。如果不设置,则文档会打印到默认打印机。
  • 选择打印页码范围 :通过 SelectPageRange 方法指定需要打印的页码范围,例如仅打印前五页。
  • 打印份数和颜色设置 :使用 Copies 属性设置打印份数,同时通过 Color 属性选择是否以彩色打印。设置为 false 表示以黑白打印。
  • 双面打印 :通过 CanDuplex 属性检查打印机是否支持双面打印。如果支持,则设置 Duplex 为默认双面打印选项。
  • 打印到默认打印机 :调用 Print 方法将加载的文档发送到指定的打印机。
  • 资源清理 :使用 Dispose 方法释放所有占用的资源,避免内存泄漏。

总结

使用 Spire.PDF for .NET 打印 PDF 文档是一个简单而强大的解决方案。通过本文中的示例代码和解析,您可以快速上手实现 PDF 文档的打印功能。希望这篇文章能够帮助您更好地利用 C# 进行 PDF 打印开发工作!

最近“死了么” APP 爆火,上次又看到一个 “撸了么( https://github.com/sky22333/luleme )”,
现在小弟也想蹭一下热点,于是花了几个小时开发了一个“做了么” APP (帮助情侣,夫妻,情人起飞的 APP ),抛砖引玉。欢迎大家打包使用,支持 Ios ,Android ,Windows ,Macos 等

github 地址: https://github.com/Chenfyuan/zuoleme

技术栈
.NET 10.0
C#
MAUI 等

精简 Excel 工作簿、删除多余或不再使用的工作表,是一种非常有效的整理方式。通过移除无关内容,可以减少冗余信息,使文件结构更加清晰,只保留最有价值的数据。删除不必要的工作表不仅有助于释放存储空间,还能让工作簿的浏览与管理更加高效、直观。

在本文中,你将学习如何使用 Spire.XLS for .NET 库,通过 C# 从 Excel 工作簿中删除指定的工作表。

安装 Spire.XLS for .NET

首先,你需要将 Spire.XLS for .NET 包中包含的 DLL 文件添加为 .NET 项目的引用。你可以通过提供的下载链接手动下载 DLL 文件并引入项目,或者直接使用 NuGet 进行安装。

PM> Install-Package Spire.XLS

在 C# 中通过索引删除工作簿中的工作表

Spire.XLS for .NET 提供了 WorksheetsCollection.RemoveAt(int index) 方法,可根据工作表在工作簿中的索引位置删除指定的工作表。

具体示例代码如下:

using Spire.Xls;
using Spire.Xls.Collections;

namespace RemoveWorksheetByIndex
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个 Workbook 对象
            Workbook wb = new Workbook();

            // 加载 Excel 文件
            wb.LoadFromFile(@"C:\Users\Administrator\Desktop\Input.xlsx");

            // 从工作簿中获取工作表集合
            WorksheetsCollection worksheets = wb.Worksheets;

            // 根据索引删除指定的工作表
            worksheets.RemoveAt(0);

            // 将工作簿保存为新的 Excel 文件
            wb.SaveToFile("RemoveByIndex.xlsx", ExcelVersion.Version2016);

            // 释放资源
            wb.Dispose();
        }
    }
}

在 C# 中通过工作表名称删除工作簿中的工作表

如果你已经知道需要删除的工作表名称,可以使用 WorksheetsCollection.Remove(string sheetName) 方法,直接按名称从工作簿中移除对应的工作表。

具体示例代码如下:

using Spire.Xls;
using Spire.Xls.Collections;

namespace RemoveWorksheetByName
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个 Workbook 对象
            Workbook wb = new Workbook();

            // 加载 Excel 文件
            wb.LoadFromFile(@"C:\Users\Administrator\Desktop\Input.xlsx");

            // 从工作簿中获取工作表集合
            WorksheetsCollection worksheets = wb.Worksheets;

            // 根据工作表名称删除指定的工作表
            worksheets.Remove("sheet2");

            // 将工作簿保存为新的 Excel 文件
            wb.SaveToFile("RemoveByName.xlsx", ExcelVersion.Version2016);

            // 释放资源
            wb.Dispose();
        }
    }
}

在 C# 中一次性删除工作簿中的所有工作表

如果需要一次性移除工作簿中的所有工作表,可以使用 WorksheetsCollection.Clear() 方法快速清空工作表集合。

具体示例代码如下:

using Spire.Xls;
using Spire.Xls.Collections;

namespace RemoveAllWorksheets
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个 Workbook 对象
            Workbook wb = new Workbook();

            // 加载 Excel 文件
            wb.LoadFromFile(@"C:\Users\Administrator\Desktop\Input.xlsx");

            // 从工作簿中获取工作表集合
            WorksheetsCollection worksheets = wb.Worksheets;

            // 删除所有工作表
            worksheets.Clear();

            // 将工作簿保存为新的 Excel 文件
            wb.SaveToFile("RemoveAllWorksheets.xlsx", ExcelVersion.Version2016);

            // 释放资源
            wb.Dispose();
        }
    }
}

申请临时许可证

如果你希望移除生成文档中的评估提示信息,或解除功能限制,请申请一个 为期 30 天的试用许可证。

精简 Excel 工作簿、删除多余或不再使用的工作表,是一种非常有效的整理方式。通过移除无关内容,可以减少冗余信息,使文件结构更加清晰,只保留最有价值的数据。删除不必要的工作表不仅有助于释放存储空间,还能让工作簿的浏览与管理更加高效、直观。

在本文中,你将学习如何使用 Spire.XLS for .NET 库,通过 C# 从 Excel 工作簿中删除指定的工作表。

安装 Spire.XLS for .NET

首先,你需要将 Spire.XLS for .NET 包中包含的 DLL 文件添加为 .NET 项目的引用。你可以通过提供的下载链接手动下载 DLL 文件并引入项目,或者直接使用 NuGet 进行安装。

PM> Install-Package Spire.XLS

在 C# 中通过索引删除工作簿中的工作表

Spire.XLS for .NET 提供了 WorksheetsCollection.RemoveAt(int index) 方法,可根据工作表在工作簿中的索引位置删除指定的工作表。

具体示例代码如下:

using Spire.Xls;
using Spire.Xls.Collections;

namespace RemoveWorksheetByIndex
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个 Workbook 对象
            Workbook wb = new Workbook();

            // 加载 Excel 文件
            wb.LoadFromFile(@"C:\Users\Administrator\Desktop\Input.xlsx");

            // 从工作簿中获取工作表集合
            WorksheetsCollection worksheets = wb.Worksheets;

            // 根据索引删除指定的工作表
            worksheets.RemoveAt(0);

            // 将工作簿保存为新的 Excel 文件
            wb.SaveToFile("RemoveByIndex.xlsx", ExcelVersion.Version2016);

            // 释放资源
            wb.Dispose();
        }
    }
}

在 C# 中通过工作表名称删除工作簿中的工作表

如果你已经知道需要删除的工作表名称,可以使用 WorksheetsCollection.Remove(string sheetName) 方法,直接按名称从工作簿中移除对应的工作表。

具体示例代码如下:

using Spire.Xls;
using Spire.Xls.Collections;

namespace RemoveWorksheetByName
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个 Workbook 对象
            Workbook wb = new Workbook();

            // 加载 Excel 文件
            wb.LoadFromFile(@"C:\Users\Administrator\Desktop\Input.xlsx");

            // 从工作簿中获取工作表集合
            WorksheetsCollection worksheets = wb.Worksheets;

            // 根据工作表名称删除指定的工作表
            worksheets.Remove("sheet2");

            // 将工作簿保存为新的 Excel 文件
            wb.SaveToFile("RemoveByName.xlsx", ExcelVersion.Version2016);

            // 释放资源
            wb.Dispose();
        }
    }
}

在 C# 中一次性删除工作簿中的所有工作表

如果需要一次性移除工作簿中的所有工作表,可以使用 WorksheetsCollection.Clear() 方法快速清空工作表集合。

具体示例代码如下:

using Spire.Xls;
using Spire.Xls.Collections;

namespace RemoveAllWorksheets
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个 Workbook 对象
            Workbook wb = new Workbook();

            // 加载 Excel 文件
            wb.LoadFromFile(@"C:\Users\Administrator\Desktop\Input.xlsx");

            // 从工作簿中获取工作表集合
            WorksheetsCollection worksheets = wb.Worksheets;

            // 删除所有工作表
            worksheets.Clear();

            // 将工作簿保存为新的 Excel 文件
            wb.SaveToFile("RemoveAllWorksheets.xlsx", ExcelVersion.Version2016);

            // 释放资源
            wb.Dispose();
        }
    }
}

申请临时许可证

如果你希望移除生成文档中的评估提示信息,或解除功能限制,请申请一个 为期 30 天的试用许可证。

temporal 官网示例

python:

@workflow.defn
class SleepForDaysWorkflow:
    # Send an email every 30 days, for the year
    @workflow.run
    async def run(self) -> None:
        for i in range(12):
            # Activities have built-in support for timeouts and retries!
            await workflow.execute_activity(
                send_email,
                start_to_close_timeout=timedelta(seconds=10),
            )

            # Sleep for 30 days (yes, really)!
            await workflow.sleep(timedelta(days=30))

ruby:


# Send an email every 30 days, for the year
class SleepForDaysWorkflow < Temporalio::Workflow::Definition
  def execute
    12.times do
      # Activities have built-in support for timeouts and retries!
      Temporalio::Workflow.execute_activity(
        SendEmailActivity,
        start_to_close_timeout: 10
      )

      # Sleep for 30 days (yes, really)!
      Temporalio::Workflow.sleep(30 * 24 * 60 * 60)
    end
  end
end

C#:

[Workflow]
public class SleepForDaysWorkflow
{
    // Send an email every 30 days, for the year
    [WorkflowRun]
    public async Task RunAsync()
    {
        for (int i = 0; i < 12; i++)
        {
            // Activities have built-in support for timeouts and retries!
            await Workflow.ExecuteActivityAsync(
                (Activities act) => act.SendEmail(),
                new() { StartToCloseTimeout = TimeSpan.FromSeconds(10) });

            // Sleep for 30 days (yes, really)!
            await Workflow.DelayAsync(TimeSpan.FromDays(30));
        }
    }
}

PHP:

class SleepForDaysWorkflow implements SleepForDaysWorkflowInterface
{
  // Send an email every 30 days.
  public function sleepForDays(): void
  {
      for ($i = 0; $i < 12; $i++) {
          // Activities have timeouts, and will be retried by default!
          $this->sendEmailActivity->sendEmail();

          // Sleep for 30 days (yes, really)!
          Workflow::sleep(30 * 24 * 60 * 60)
      }
  }
}

感觉对于 java 程序员 php 的心智负担好小啊

temporal 官网示例

python:

@workflow.defn
class SleepForDaysWorkflow:
    # Send an email every 30 days, for the year
    @workflow.run
    async def run(self) -> None:
        for i in range(12):
            # Activities have built-in support for timeouts and retries!
            await workflow.execute_activity(
                send_email,
                start_to_close_timeout=timedelta(seconds=10),
            )

            # Sleep for 30 days (yes, really)!
            await workflow.sleep(timedelta(days=30))

ruby:


# Send an email every 30 days, for the year
class SleepForDaysWorkflow < Temporalio::Workflow::Definition
  def execute
    12.times do
      # Activities have built-in support for timeouts and retries!
      Temporalio::Workflow.execute_activity(
        SendEmailActivity,
        start_to_close_timeout: 10
      )

      # Sleep for 30 days (yes, really)!
      Temporalio::Workflow.sleep(30 * 24 * 60 * 60)
    end
  end
end

C#:

[Workflow]
public class SleepForDaysWorkflow
{
    // Send an email every 30 days, for the year
    [WorkflowRun]
    public async Task RunAsync()
    {
        for (int i = 0; i < 12; i++)
        {
            // Activities have built-in support for timeouts and retries!
            await Workflow.ExecuteActivityAsync(
                (Activities act) => act.SendEmail(),
                new() { StartToCloseTimeout = TimeSpan.FromSeconds(10) });

            // Sleep for 30 days (yes, really)!
            await Workflow.DelayAsync(TimeSpan.FromDays(30));
        }
    }
}

PHP:

class SleepForDaysWorkflow implements SleepForDaysWorkflowInterface
{
  // Send an email every 30 days.
  public function sleepForDays(): void
  {
      for ($i = 0; $i < 12; $i++) {
          // Activities have timeouts, and will be retried by default!
          $this->sendEmailActivity->sendEmail();

          // Sleep for 30 days (yes, really)!
          Workflow::sleep(30 * 24 * 60 * 60)
      }
  }
}

感觉对于 java 程序员 php 的心智负担好小啊