冰蓝科技
|
028-81705109
|
|
微信扫一扫
|

Spire.Cloud 纯前端文档控件

Spire.PDF for Python 12.6.0 现已正式发布。该版本主要开放 PdfTable 与 PdfGrid 的 DataSource 属性,支持结构化数据的直接绑定。详情请查阅以下内容。

新功能:


获取 Spire.PDF for Python 12.6.0 请点击:

https://www.e-iceblue.cn/Downloads/Spire-PDF-Python.html

Spire.Doc for Java 14.6.0 现已正式发布。该版本增强了 Word 到 PDF 的转换功能,并修复了一个更新交叉引用域不正确的问题。详情如下。

问题修复:


获取 Spire.Doc for Java 14.6.0 请点击:

https://www.e-iceblue.cn/Downloads/Spire-Doc-JAVA.html

在 Java 中读取 Excel 文件

Java 中读取 Excel 文件是企业应用中的常见需求,尤其是在处理报表、财务数据、用户信息或第三方系统集成时。无论你是在构建数据导入功能、执行电子表格分析,还是将 Excel 解析集成到 Web 应用中,掌握如何高效地在 Java 中读取 Excel 文件都非常重要。

在本教程中,你将学习如何使用 Java 读取 .xls 和 .xlsx 格式的 Excel 文件。我们将通过实用的 Java 代码示例,演示如何处理大型文件、从 InputStream 读取 Excel,以及逐行提取指定内容等操作。

1. 搭建 Java 项目

要在 Java 中读取 Excel 文件,你需要一个支持电子表格文件格式的库。Spire.XLS for Java 同时支持 .xls(旧版 Excel 格式)和 .xlsx(基于 XML 的现代格式),并提供高级 API,使 Excel 文件读取更加简单高效。

将 Spire.XLS 添加到项目中

如果你使用 Maven,请将以下内容添加到 pom.xml 中:

<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.xls</artifactId>
        <version>16.9.2</version>
    </dependency>
</dependencies>

如果你未使用 Maven,也可以从 Spire.XLS 官网手动下载 JAR 包并添加到 classpath 中。

对于较轻量级的 Excel 处理需求,你也可以选择使用 Free Spire.XLS for Java。

2. 如何在 Java 中读取 XLSX 和 XLS 文件

Java 程序可以通过加载工作簿(Workbook),然后遍历工作表、行和单元格来读取 Excel 文件。.xlsx 是现代 Excel 中最常用的格式,而 .xls 是其早期的二进制格式。幸运的是,Spire.XLS 使用同一套代码即可无缝支持两种格式。

加载并读取 Excel 文件(XLSX 或 XLS)

下面是一个加载 Excel 文件并打印其内容的基础示例:

import com.spire.xls.*;

public class ReadExcel {
    public static void main(String[] args) {
        // 创建 Workbook 对象并加载 Excel 文件
        Workbook workbook = new Workbook();
        workbook.loadFromFile("data.xlsx"); // 或 "data.xls"

        // 获取第一个工作表
        Worksheet sheet = workbook.getWorksheets().get(0);

        // 遍历已使用的行和列
        for (int i = 1; i <= sheet.getLastRow(); i++) {
            for (int j = 1; j <= sheet.getLastColumn(); j++) {

                // 获取单元格文本
                String cellText = sheet.getCellRange(i, j).getValue();
                System.out.print(cellText + "\t");
            }
            System.out.println();
        }
    }
}

你可以直接将文件路径替换为 .xls 文件,代码无需修改。这意味着你可以使用同一套 Java 代码读取不同格式的 Excel 文件。

读取的 Excel 文件以及控制台输出结果如下图所示:

加载并读取 Excel 文件

使用 Row 对象逐行读取 Excel 文件

在用户数据校验或业务规则处理等场景下,将每一行作为一条数据记录进行处理通常更加直观。此时,你可以通过 getRows() 方法,使用行对象逐行读取 Excel:

for (int i = 0; i < sheet.getRows().length; i++) {

    // 获取一行
    CellRange row = sheet.getRows()[i];

    if (row != null && !row.isBlank()) {

        for (int j = 0; j < row.getColumns().length; j++) {

            String text = row.getColumns()[j].getText();
            System.out.print((text != null ? text : "") + "\t");
        }

        System.out.println();
    }
}

这种方式特别适合批量处理 Excel 数据,或仅需按行处理数据的场景。

从 InputStream 读取 Excel 文件

在 Web 应用或云服务中,Excel 文件通常会以流的形式接收。下面演示如何在 Java 中通过 InputStream 读取 Excel 文件:

import com.spire.xls.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

public class ReadExcel {
    public static void main(String[] args) throws FileNotFoundException {

        // 创建 InputStream
        InputStream stream = new FileInputStream("data.xlsx");

        // 从流中加载 Excel 文件
        Workbook workbook = new Workbook();
        workbook.loadFromStream(stream);

        System.out.println("Excel 文件加载成功。");
    }
}

这种方式非常适用于处理文件上传、邮件附件或远程存储中的 Excel 文件。

读取不同格式的 Excel 单元格值

加载 Excel 文件并获取单元格对象后,Spire.XLS 支持以多种形式读取单元格内容——格式化文本、原始值、公式等。

示例如下:

CellRange cell = sheet.getRange().get(2, 1); // B2

// 格式化文本(Excel 中显示的内容)
String text = cell.getText();

// 原始字符串值
String value = cell.getValue();

// 通用对象(数字、布尔值、日期等)
Object rawValue = cell.getValue2();

// 公式(如果存在)
String formula = cell.getFormula();

// 公式计算结果
String result = cell.getEnvalutedValue();

// 数值类型
double number = cell.getNumberValue();

// 日期类型
java.util.Date date = cell.getDateTimeValue();

// 布尔类型
boolean bool = cell.getBooleanValue();

提示:getValue2() 更适合灵活处理数据,因为它返回真实的数据对象。getText() 更适合获取与 Excel 中显示一致的内容。

你可能还想要知道:如何在 Java 中将数据写入 Excel 文件

3. 在 Java 中读取大型 Excel 文件的最佳实践

当 Excel 文件包含数万行数据或多个工作表时,性能可能会成为问题。为了确保 Java 应用能够高效读取大型 Excel 文件,建议遵循以下最佳实践:

  • 仅加载需要的工作表
  • 仅访问相关的列或行
  • 避免将整个工作表一次性存入内存
  • 采用逐行读取模式

下面是一个仅处理非空行的高效读取示例:

for (int i = 1; i <= sheet.getRows().length; i++) {

    Row row = sheet.getRows()[i];

    if (row != null && !row.isBlank()) {

        // 仅处理有数据的行
    }
}

尽管 Spire.XLS 能高效地管理内存,但遵循这些实践能够帮助你的 Java Excel 读取逻辑更好地扩展。

另请参阅:使用 Java 删除 Excel 中的空白行和列

4. 完整示例:Java 读取 Excel 文件程序

下面是一个完整的可运行 Java 示例,用于读取一个包含姓名、电子邮件、年龄、部门和状态等扩展列的 Excel 文件(users.xlsx)。代码仅提取前三列(姓名、邮箱、年龄),并筛选出年龄在 30 岁及以上的用户输出。

import com.spire.xls.*;

public class ExcelReader {

    public static void main(String[] args) {

        Workbook workbook = new Workbook();
        workbook.loadFromFile("users.xlsx");

        Worksheet sheet = workbook.getWorksheets().get(0);

        System.out.println("姓名\t电子邮件\t年龄");

        for (int i = 2; i <= sheet.getLastRow(); i++) {

            String name = sheet.getCellRange(i, 1).getValue();
            String email = sheet.getCellRange(i, 2).getValue();
            String ageText = sheet.getCellRange(i, 3).getValue();

            int age = 0;

            try {
                age = Integer.parseInt(ageText);

            } catch (NumberFormatException e) {

                continue;  // 跳过年龄数据无效的行
            }

            if (age >= 30) {

                System.out.println(name + "\t" + email + "\t" + age);
            }
        }
    }
}

程序运行结果如下图所示:

Java:读取 Excel 文件

该示例展示了如何在 Java 中读取 Excel 指定单元格的数据,并输出有意义的表格信息,同时还能对数据(如年龄)进行筛选处理。

5. 总结

本文介绍了如何使用 Spire.XLS for Java 在 Java 中读取 Excel 文件,包括 .xls 和 .xlsx 两种格式。你已经学习了:

  • 搭建具有 Excel 读取功能的 Java 项目
  • 使用 Java 以逐行或基于流的方式读取 Excel 文件
  • 使用相同的 API 处理旧版和现代 Excel 格式
  • 在处理大型 Excel 文件时应用最佳实践

无论你是处理上传的 Excel 文件、静态报表,还是流式数据,本教程中的示例都能够帮助你在 Java 应用中构建健壮的 Excel 处理功能。

如果你想解锁所有限制并体验完整的 Excel 处理能力,可以申请免费的临时许可证。

6. FAQs 常见问题

问题1:如何在 Java 中动态读取 Excel 文件?

答:要在 Java 中动态读取 Excel 文件——特别是当行数或列数未知时——你可以使用 getLastRow() 和 getLastColumn() 方法在运行时确定数据范围。这确保你的程序能适应各种大小的电子表格,而无需硬编码限制。

问题2:如何在 Java 中提取 Excel 数据?

答:你可以通过遍历工作簿中的单元格来提取 Excel 数据,例如:getCellRange(row, column).getValue()。像 Spire.XLS for Java 这样的库能够简化该过程,并同时支持 .xls 与 .xlsx 格式。

问题3:如何在 Java 中读取 CSV 文件?

答:如果 Excel 数据保存为 CSV 文件,可以使用 Java 的 BufferedReader 或文件流读取。

此外,Spire.XLS 也支持直接解析 CSV——你可以通过指定分隔符来加载 CSV 文件,例如 Workbook.loadFromFile("data.csv", ",")。这样你就能使用同一套 API 处理 CSV 与 Excel 文件。

问题4:如何通过 InputStream 在 Java 中读取 Excel 文件?

答:在服务端应用中(例如文件上传场景),通过 InputStream 读取 Excel 文件非常常见。使用 Spire.XLS 时,只需调用 workbook.loadFromStream(inputStream),随后即可像处理普通 Excel 文件一样进行读取和操作。

C# HTML 转 Markdown 图文教程

HTML 广泛用于网页、在线文章、帮助文档、产品说明和富文本内容,而 Markdown (.md) 则更适合文档编写、技术写作、版本控制以及基于文本的发布流程。与 HTML 相比,Markdown 语法更轻量,内容结构更清晰,也更容易在 GitHub、静态网站生成器、博客系统和开发者文档平台中维护。

如果你需要将已有的 HTML 内容迁移到 Markdown 工作流中,手动复制和重新排版不仅耗时,还容易遗漏链接、图片、列表、表格或文本样式。对于大量 HTML 文件、CMS 导出的内容或动态生成的网页片段,使用代码自动转换会更加高效和稳定。

在本教程中,我们将逐步讲解如何使用 C# 和 Spire.Doc 将 HTML 转换为 Markdown,包括转换本地 HTML 文件、HTML 字符串、HTML 流,以及批量转换多个 HTML 文件的方法。文章还会介绍常见 HTML 元素在 Markdown 中的转换效果,并提供一些实用的问题排查建议。

目录

何时需要将 HTML 转换为 Markdown?

将 HTML 转换为 Markdown 适用于希望以更简洁、文本友好的格式重用网页或富文本内容的场景。尤其是在技术文档、知识库迁移、内容管理系统重构或自动化发布流程中,将 HTML 转为 Markdown 可以让内容更容易维护、审查和复用。

常见用例包括:

  • 将 HTML 文章或 CMS 内容导入基于 Markdown 的文档系统。
  • 为 GitHub、静态网站生成器或开发者门户准备内容。
  • 将富文本编辑器的输出转换为可编辑的 Markdown 文件。
  • 简化 HTML 页面以便版本控制、内容审查或长期维护。
  • 导出帮助中心文章、产品描述、博客内容或技术说明为 .md 文件。
  • 在自动化文档生成流程中,将网页内容转换为更适合发布和存档的文本格式。

对于开发者来说,HTML 转 Markdown 的关键不仅是“转换格式”,还包括尽可能保留原始内容结构,例如标题层级、段落、链接、图片、列表和表格等。使用 C# 自动处理这些内容,可以减少人工整理成本,并提高批量处理的一致性。

安装 C# HTML 转 Markdown 库

要在 C# 中实现 HTML 转 Markdown,需要在项目中添加 Spire.Doc for .NET 库。该独立文档处理库可以解析 HTML 内容,并将其导出为 Markdown 文件。它不依赖 Microsoft Word,也不需要在服务器上安装 Office Interop 程序集,因此更适合桌面应用、Web 应用、后台服务以及服务器端文档处理场景。

方法 1:通过 NuGet 包管理器安装

在 NuGet 包管理器控制台运行以下命令:

Install-Package Spire.Doc

方法 2:手动下载并引用 DLL

如果你的开发环境无法联网,或者项目中不方便使用 NuGet,也可以手动下载并引用 DLL 文件:

  1. 下载 & 解压: 从 官方下载页面 获取 Spire.Doc for .NET 包并解压。
  2. 添加引用: 在 Visual Studio 的解决方案资源管理器中,右键 Dependencies(或 References)> Add Project Reference(或 Add Reference)> Browse,选择与目标 .NET Framework、.NET Core 或 .NET 版本匹配的 Spire.Doc.dll。

注意: Markdown 支持需 Spire.Doc for .NET 12.3.12 或更高版本。为避免格式导出不完整或 API 不可用,建议在开始开发前确认项目中引用的是支持 Markdown 导出的版本。

将 HTML 文件转换为 Markdown

如果 HTML 内容已经保存为本地 .html 或 .htm 文件,可以直接使用 Document 对象加载 HTML 文件,并将其保存为 Markdown 文件。这是最基础也最常见的转换方式,适合处理静态网页、离线帮助文档、HTML 格式的报告、CMS 导出的页面或本地存档内容。

C# 示例代码

using Spire.Doc;
using Spire.Doc.Documents;

namespace ConvertHtmlFileToMarkdown
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Document document = new Document())
            {
                document.LoadFromFile("input.html", FileFormat.Html, XHTMLValidationType.None);
                document.SaveToFile("output.md", FileFormat.Markdown);
            }
        }
    }
}

代码说明:

  • using (Document document = new Document()):创建 Document 对象,并确保转换完成后自动释放资源。
  • LoadFromFile("input.html", FileFormat.Html, XHTMLValidationType.None):读取本地 HTML 文件,并指定输入格式为 HTML。XHTMLValidationType.None 表示不进行严格 XHTML 验证,这对于处理普通网页 HTML 更加灵活。
  • SaveToFile("output.md", FileFormat.Markdown):将加载后的文档模型导出为 Markdown 文件。标题、段落、加粗文本、列表、链接和图片等常见内容会被转换为对应的 Markdown 语法。

输出示例:

C# HTML 文件转 Markdown 输出示例

对于结构清晰的 HTML 文件,例如包含标准标题、段落、列表和链接的页面,转换后的 Markdown 通常更容易阅读和维护。如果源 HTML 中包含大量内联 CSS、复杂布局或脚本内容,导出的 Markdown 会更偏向保留文本内容和基础结构,而不是完整保留网页视觉样式。

将 HTML 字符串转换为 Markdown

在实际开发中,HTML 内容并不总是以物理文件形式存在。它可能来自数据库字段、API 响应、CMS 编辑器、富文本输入框,或者由程序动态生成。在这种情况下,可以直接将 HTML 字符串插入到文档对象中,再保存为 Markdown 文件。

与先把字符串写入临时 HTML 文件再转换相比,直接处理 HTML 字符串可以减少中间文件操作,也更适合集成到 Web 应用、后台服务或内容管理系统中。

C# 示例代码

using Spire.Doc;
using Spire.Doc.Documents;

namespace ConvertHtmlStringToMarkdown
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Document document = new Document())
            {
                Section section = document.AddSection();
                Paragraph paragraph = section.AddParagraph();

                string htmlString = @"
                    <h1>HTML to Markdown Conversion</h1>
                    <p>This is a sample paragraph with a <a href='https://www.example.com'>link</a>.</p>
                    <ul>
                        <li>First item</li>
                        <li>Second item</li>
                        <li>Third item</li>
                    </ul>";

                paragraph.AppendHTML(htmlString);
                document.SaveToFile("html-string-output.md", FileFormat.Markdown);
            }
        }
    }
}

关键方法说明:

  • document.AddSection() & section.AddParagraph():空的 Document 对象本身不包含可承载内容的文档结构,因此需要先添加节和段落。
  • paragraph.AppendHTML(htmlString):解析 HTML 字符串,并将支持的 HTML 元素插入到当前段落所在的文档结构中。
  • document.SaveToFile("html-string-output.md", FileFormat.Markdown):将插入后的文档内容保存为 Markdown 文件。

输出示例:

C# HTML 字符串转 Markdown 输出示例

这种方法非常适合处理动态 HTML 片段。例如,当用户在富文本编辑器中提交内容后,系统可以立即将其转换为 Markdown 并保存到数据库、文档仓库或 Git 版本库中。需要注意的是,如果 HTML 字符串中包含外部图片、相对链接或复杂嵌套结构,转换后仍应检查路径和格式是否符合目标 Markdown 平台的要求。

将 HTML 流转换为 Markdown

在云端应用、Web API、后台任务和企业级文档处理系统中,HTML 内容通常以流形式传递,而不是从固定路径读取。例如,用户上传的 HTML 文件可能直接进入内存流,API 返回的 HTML 内容也可能在内存中被处理。此时,可以使用 LoadFromStream() 和 SaveToStream() 在内存中完成 HTML 到 Markdown 的转换。

这种方式适用于不希望在服务器上生成临时文件的场景,有助于减少磁盘 I/O,提高处理流程的安全性和灵活性。对于 ASP.NET 应用、文件转换服务、云函数或微服务架构来说,流式转换尤其有用。

C# 示例代码

using System.IO;
using System.Text;
using Spire.Doc;
using Spire.Doc.Documents;

namespace ConvertHtmlStreamToMarkdown
{
    class Program
    {
        static void Main(string[] args)
        {
            string htmlContent = "<h1>HTML Stream to Markdown Stream</h1><p>This process happens entirely in memory.</p>";
            byte[] htmlBytes = Encoding.UTF8.GetBytes(htmlContent);

            using (MemoryStream inputStream = new MemoryStream(htmlBytes))
            using (MemoryStream outputStream = new MemoryStream())
            using (Document document = new Document())
            {
                document.LoadFromStream(inputStream, FileFormat.Html, XHTMLValidationType.None);
                document.SaveToStream(outputStream, FileFormat.Markdown);

                outputStream.Position = 0;
                using (StreamReader reader = new StreamReader(outputStream, Encoding.UTF8))
                {
                    string markdownResult = reader.ReadToEnd();
                    System.Console.WriteLine(markdownResult);
                }
            }
        }
    }
}

代码说明:

  • Encoding.UTF8.GetBytes(htmlContent):将 HTML 字符串转换为 UTF-8 字节数组,模拟内存中的 HTML 输入数据。
  • MemoryStream inputStream = new MemoryStream(htmlBytes):创建输入流,用于加载 HTML 内容。
  • document.LoadFromStream(inputStream, FileFormat.Html, XHTMLValidationType.None):从流中读取 HTML 数据。
  • document.SaveToStream(outputStream, FileFormat.Markdown):将转换后的 Markdown 内容保存到输出流。
  • outputStream.Position = 0:读取输出流之前必须将流的位置重置到开头,否则可能读取不到内容。

如果你要在 Web API 中返回 Markdown 文件,可以将 outputStream 转换为字节数组,并作为文件响应返回给前端。这样整个转换过程都可以在内存中完成,无需保存中间文件。

批量转换多个 HTML 文件

对于大规模发布流程,手动逐个转换 HTML 文件效率较低,也容易出现遗漏。通过 C# 循环扫描文件夹,可以自动将多个 HTML 文件转换为对应的 Markdown 文件。这种方式适用于文档迁移、网站内容归档、帮助中心批量导出、知识库重构或静态内容转换流程。

下面的示例会读取指定文件夹中的所有 .html 文件,并将每个文件转换为同名的 .md 文件,保存到目标文件夹中。

C# 示例代码

using Spire.Doc;
using Spire.Doc.Documents;
using System;
using System.IO;

namespace BatchConvertHtmlToMarkdown
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string inputFolder = @"C:\HtmlFiles";
            string outputFolder = @"C:\MarkdownFiles";

            Directory.CreateDirectory(outputFolder);
            string[] htmlFiles = Directory.GetFiles(inputFolder, "*.html");

            foreach (string htmlFile in htmlFiles)
            {
                try
                {
                    string fileName = Path.GetFileNameWithoutExtension(htmlFile);
                    string outputPath = Path.Combine(outputFolder, fileName + ".md");

                    using (Document document = new Document())
                    {
                        document.LoadFromFile(htmlFile, FileFormat.Html, XHTMLValidationType.None);
                        document.SaveToFile(outputPath, FileFormat.Markdown);
                    }

                    Console.WriteLine($"已转换: {Path.GetFileName(htmlFile)}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"转换失败: {Path.GetFileName(htmlFile)}");
                    Console.WriteLine($"错误: {ex.Message}");
                }
            }

            Console.WriteLine("HTML 批量转换为 Markdown 完成。");
        }
    }
}

代码说明:

  • Directory.CreateDirectory(outputFolder):如果输出目录不存在,则自动创建。
  • Directory.GetFiles(inputFolder, "*.html"):获取输入目录下所有 .html 文件。
  • Path.GetFileNameWithoutExtension(htmlFile):获取不带扩展名的文件名,用于生成对应的 .md 文件名。
  • try...catch:捕获单个文件转换过程中的异常,避免某个文件失败导致整个批量任务中断。

如果你的源文件夹中同时包含 .html 和 .htm 文件,可以额外扫描 *.htm 文件,或者将两类文件合并后统一处理。对于大型转换任务,也建议在日志中记录失败文件路径、错误原因和转换时间,便于后续检查和重试。

哪些 HTML 元素可以转换为 Markdown?

HTML 和 Markdown 的设计目标不同。HTML 更适合表达复杂网页结构、样式和交互,而 Markdown 更强调内容本身和基础文档结构。因此,在 HTML 转 Markdown 时,内容型元素通常更容易保留,例如标题、段落、列表、链接、图片和简单表格;而布局型、样式型或脚本型内容可能会被简化或忽略。

例如,Markdown 的表格语法只适合基础行列结构。如果源 HTML 包含合并单元格、嵌套表格、复杂样式的表格,转换后的 Markdown 表格可能需要手动调整。对于需要保留复杂表格数据的场景,也可以考虑使用 C# 将 HTML 转换为 Excel,再进行后续处理。

以下是常见 HTML 元素与 Markdown 输出结果对照表:

HTML 元素 对应 Markdown 语法
<h1> 到 <h6> # 到 ######(标题)
<p> 普通段落
<strong>, <b> **加粗**
<em>, <i> *斜体*
<ul>, <ol>, <li> 无序/有序列表
<a> [链接文本](URL)
<img> ![替代文本](图片路径/URL)
<table> Markdown 表格
<code> 行内代码
<pre> 代码块
<br> 换行
<div>, <section> 通常简化为普通内容结构
CSS 样式 部分保留或移除
JavaScript 不支持转换为 Markdown 内容

提示: 实际输出可能因源 HTML 结构、标签嵌套方式以及目标 Markdown 编辑器或平台的支持范围而有所差异。转换完成后,建议在目标平台中预览 Markdown 文件,确认标题、列表、链接、图片和表格是否符合预期。

常见 HTML 转 Markdown 问题排查

在实际转换过程中,HTML 源文件的结构、编码、资源路径和样式复杂度都会影响 Markdown 输出效果。下面列出一些常见问题及处理建议:

  • 图片无法显示: 确保图片路径有效;如果源 HTML 使用相对路径,转换后的 Markdown 文件位置发生变化时,图片路径可能需要重新调整。对于线上发布场景,可以考虑使用完整 URL。
  • 表格显示异常: Markdown 仅支持基础表格。对于包含合并单元格、嵌套表格或复杂样式的 HTML 表格,建议先简化源 HTML 表格,或在转换后手动调整生成的 Markdown 表格。
  • 特殊字符异常: 这通常是编码问题。请确保源 HTML 文件使用 UTF-8 编码,并使用支持 UTF-8 的编辑器打开生成的 Markdown 文件。
  • 额外空行: 删除源 HTML 中多余的空标签、嵌套 div 或冗余 br 标签。转换完成后,也可以在 Markdown 文件中使用查找替换快速清理连续空行。
  • 链接路径不正确: 检查 <a> 标签中的 href 是否为有效 URL 或正确的相对路径。迁移到新文档目录后,相对路径可能需要重新映射。
  • 样式没有保留: Markdown 本身不适合保留复杂 CSS 样式。如果原 HTML 依赖大量样式控制视觉效果,转换后应重点检查内容结构,而不是期望完全还原网页外观。

总结

使用 Spire.Doc for .NET,开发者可以在 C# 中轻松实现 HTML 到 Markdown 的转换。无论 HTML 内容来自本地文件、动态字符串、内存流,还是整个文件夹中的批量页面,都可以通过相应的 API 完成自动化处理。对于文档迁移、内容归档、技术写作平台重构或自动化发布流程来说,HTML 转 Markdown 可以显著提升内容维护效率,并让文档更适合版本控制和长期管理。

如果你还需要反向转换,可参考 C# Markdown 转 HTML 教程。

常见问题

Q1: 转换过程中图片会被保留吗?

A1: 会。标准 HTML <img> 标签可以转换为 Markdown 图片语法 ![Alt Text](图片路径/URL)。但需要确保源 HTML 中的图片 URL 或文件路径有效,否则 Markdown 文件中的图片可能无法正常显示。

Q2: 可以在内存中直接转换 HTML 字符串或流吗?

A2: 可以。HTML 字符串可以通过 AppendHTML() 插入文档,HTML 流可以通过 LoadFromStream() 加载,并使用 SaveToStream() 在内存中导出为 Markdown,无需生成临时文件。

Q3: 可以一次转换多个 HTML 文件吗?

A3: 可以。你可以使用 foreach 循环遍历指定文件夹中的 *.html 文件,将每个 HTML 文件加载到 Document 对象中,再分别保存为 .md 文件。

Q4: 是否需要安装 Microsoft Word?

A4: 不需要。Spire.Doc for .NET 是独立的文档处理库,不依赖 Microsoft Word,也不需要安装 Office Interop 程序集。

Q5: HTML 中的 CSS 样式会完整保留到 Markdown 中吗?

A5: 通常不会。Markdown 主要用于表达文档内容和基础结构,不适合保留复杂 CSS 样式。转换时应重点关注标题、段落、列表、链接、图片和表格等内容结构是否正确。

Q6: 转换后的 Markdown 文件可以用于 GitHub 或静态网站生成器吗?

A6: 可以。转换后的 .md 文件通常可以继续在 GitHub、静态网站生成器、博客系统或文档平台中编辑和发布。发布前建议预览一次,确认链接、图片路径和表格显示效果符合目标平台要求。

我们很高兴地宣布,Spire.Office 11.5.0 正式发布。在此版本中,Spire.Doc 增强了 Word 到 PDF 转换功能。Spire.XLS 增强了 Excel 到 EMF 的转换功能。Spire.Presentation 优化了从 PowerPoint 到 PDF 的转换功能。Spire.PDF 新增支持 SHA-2 和 SHA-256 数字签名算法。此外,本版本还修复了大量已知问题。

本次发布集成了以下组件的最新版本:Spire.Doc、Spire.PDF、Spire.XLS、Spire.Presentation、Spire.Barcode、Spire.DocViewer、Spire.PDFViewer、Spire.Email、Spire.Spreadsheet 和 Spire.OfficeViewer。

版本信息如下:


获取Spire.Office 11.5.0,请点击:

https://www.e-iceblue.cn/Downloads/Spire-Office-NET.html

Spire.Doc

问题修复:

Spire.XLS

问题修复:

Spire.Presentation

问题修复:

Spire.PDF

新功能:

问题修复:

JavaScript 和 React 中的 Excel 文件导出

现代 Web 应用程序经常需要直接在浏览器中生成可下载的 Excel 报表,而无需依赖后端服务。无论是构建数据仪表板、报表工具还是数据密集型业务应用程序,浏览器端的电子表格导出已成为前端开发的常见需求。

这一需求的挑战在于,如何在不同浏览器中创建兼容的 Excel 文件,同时保持格式、支持多种输出格式并确保快速下载——所有这些都不需要将敏感数据发送到服务器。传统方法通常需要复杂的服务器端处理,或者依赖于功能有限的客户端库。

Spire.XLS for JavaScript 使开发人员能够使用 WebAssembly 技术完全在浏览器中生成、导出并使用 JS 下载 Excel 文件。这种方法提供了真正的客户端 Excel 生成功能,支持多种格式,包括 XLS、XLSX、XLSB、ODS、PDF、XML 和 XPS。

本文将演示如何在现代 JavaScript 和 React 应用程序中使用浏览器端处理和 Spire.XLS for JavaScript 生成并下载 Excel 文件。内容涵盖基础文件生成、基于流的导出、React 集成以及 HTML 表格转换,并提供实用的代码示例。

快速导航


为什么要在浏览器中导出 Excel

与传统的服务器端方法相比,浏览器端 Excel 导出具有显著优势:

  • 增强隐私保护 – 敏感数据永远不会离开客户端设备,降低安全风险并减少合规性问题
  • 更快的下载速度 – 消除服务器往返请求,减少延迟并改善用户体验
  • 无需服务器端处理 – 降低后端基础设施成本并消除服务器瓶颈
  • 支持离线工作 – 即使没有网络连接,客户端生成功能也能正常运行
  • 可扩展架构 – 每个用户的浏览器处理自己的导出任务,分散计算负载
  • 框架无关 – 可与 React、Vue、Angular 和原生 JavaScript 应用程序无缝协作

通过在浏览器中实现 Excel 导出功能,开发人员可以创建响应迅速、安全且经济高效的解决方案,这些方案能够随用户需求自然扩展。


安装 Spire.XLS for JavaScript

在 JavaScript 中生成和下载 Excel 文件之前,需要安装 Spire.XLS for JavaScript 并在开发环境中进行配置。

通过 npm 安装

可以使用 npm 安装 Spire.XLS for JavaScript:

npm i spire.xls

安装完成后,在项目中引入该库:

import { Workbook } from '@e-iceblue/spire.xls';

注意:当前的 WebAssembly 运行时通过 spire.office 包结构在内部提供,即使从 npm 安装 spire.xls 也是如此。这就是为什么初始化导入引用的是 /node_modules/spire.office/。

手动安装

也可以从 e-iceblue 网站下载软件包,并将依赖项复制到项目目录中。

有关详细的设置说明,请参阅 Spire.XLS for JavaScript 入门指南。

初始化 WASM 模块

在使用 Spire.XLS 之前,必须初始化 WebAssembly 模块。初始化过程会加载所需资源并设置运行时环境:

// 首先导入并初始化公共模块
import('/node_modules/spire.office/spire.common.js').then(async (commonModule) => {
    // 初始化 WASM 运行时
    await commonModule.initializeWasm();
    
    // 加载 XLS 模块
    await import('/node_modules/spire.office/spire.xls.js');
    
    console.log('Spire.XLS 已就绪');
});

重要说明:

  • 在访问 window.spirexls 或 window.xlswasm 之前必须进行初始化
  • 浏览器会在首次加载时下载所需的 WebAssembly 资源
  • 在执行 Excel 操作之前,务必验证模块是否存在
  • 本文使用 spire.office v11.4.1+ 版本。模块通过 window.spirexls 或 window.xlswasm 访问。

Spire.XLS for JavaScript 可与所有主流前端框架和构建工具无缝集成:

  • React – 与(useState、useEffect)配合使用,实现状态驱动的 Excel 导出组件
  • Vue.js – 与 Vue 的响应式数据系统和生命周期方法集成
  • Angular – 兼容 Angular 服务和依赖注入模式
  • 原生 JavaScript 及现代 Web 特性 – 支持 ES Modules、Blob、File API 等浏览器原生能力,可灵活集成到各类 Web 应用中

WebAssembly 模块在应用程序初始化时加载一次,并可在多个组件之间共享,这使得它对于多页面应用程序非常高效,无论选择哪种框架。


在 JavaScript 中下载 Excel 文件

以下示例演示如何使用 Spire.XLS for JavaScript 生成 Excel 文件并直接在浏览器中下载。

创建并下载 XLSX 文件

// 确保 WASM 模块已初始化
if (!window.spirexls && !window.xlswasm) {
    console.error("Spire.XLS 未初始化。");
    return;
}

// 获取已初始化的 WebAssembly 模块
const wasmModule = window.spirexls || window.xlswasm;

// 创建新工作簿
const workbook = new wasmModule.Workbook();
const worksheet = workbook.Worksheets.get(0);

// 创建示例数据
const products = [
    ["产品", "数量", "价格"],
    ["笔记本电脑", 10, 999.99],
    ["鼠标", 50, 24.99]
]

// 将数据插入工作表
for (let i = 0; i < products.length; i++) {
    for (let j = 0; j < products[i].length; j++) {
        if (typeof products[i][j] === "string") {
            worksheet.Range.get({ row: i + 1, column: j + 1 }).Text = products[i][j];
        }
        else {
            worksheet.Range.get({ row: i + 1, column: j + 1 }).NumberValue = products[i][j];
        }
    }
}

// 添加总计列
worksheet.Range.get({ row: 1, column: products[0].length + 1 }).Text = "总计";
worksheet.Range.get({ row: 2, column: products[0].length + 1 }).Formula = "=B2*C2";
worksheet.Range.get({ row: 3, column: products[0].length + 1 }).Formula = "=B3*C3";

// 将工作簿保存到虚拟文件系统 (VFS)
const outputFileName = "Report.xlsx";

workbook.SaveToFile({
    fileName: outputFileName,
    version: wasmModule.ExcelVersion.Version2016
});

// 释放工作簿资源
workbook.Dispose();

// 从 VFS 读取生成的文件
const fileArray =
    window.dotnetRuntime.Module.FS.readFile(outputFileName);

// 创建 Blob 对象
const excelBlob = new Blob(
    [fileArray],
    {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    }
);

// 触发浏览器下载
const url = URL.createObjectURL(excelBlob);
const a = document.createElement("a");
a.href = url;
a.download = outputFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);

以下是生成的 XLSX 文件预览:

在 JavaScript 中生成并下载 Excel 文件

导出流程工作原理

  1. 创建工作簿并填充工作表数据
  2. 将工作簿保存到 WebAssembly 虚拟文件系统 (VFS)
  3. 从 VFS 读取生成的 XLSX 文件
  4. 将文件数据转换为 Blob 对象
  5. 使用临时 URL 触发浏览器下载

关于虚拟文件系统 (VFS)

SaveToFile() 生成的文件存储在 WebAssembly 虚拟文件系统中,而不是用户的物理磁盘上。这种内存文件系统允许 Spire.XLS 在浏览器环境中安全地执行标准文件操作。下载后的 XLSX 文件是在从 VFS 读取生成的文件数据并将其转换为浏览器 Blob 对象后创建的。

此方法的优势

  • 完全在浏览器中运行
  • 无需服务器端处理
  • 使用标准的浏览器 Blob 下载 API
  • 支持使用 Spire.XLS 直接生成并格式化 XLSX 文件

如需处理轻量级数据交换格式,可以进一步探索 如何使用 JavaScript 将 Excel 文件转换为 CSV 并将 CSV 数据导入 Excel。


在 JavaScript 中将 HTML 表格导出为 Excel

在仪表板和报表应用程序中,业务数据通常以 HTML 表格的形式显示。与其手动重建电子表格结构,不如使用 Spire.XLS for JavaScript 直接将现有的前端表格转换为 Excel 工作簿。

以下示例演示了一个完整的浏览器端工作流程,该流程:

  • 从页面读取现有的 HTML 表格
  • 将 HTML 表格转换为 Excel 工作簿
  • 应用 Excel 原生格式
  • 直接在浏览器中下载生成的 XLSX 文件

HTML 表格导出示例

async function exportTableToExcel() {

    if (!window.spirexls && !window.xlswasm) {
        alert("Spire.XLS 模块尚未加载。");
        return;
    }

    const button = document.getElementById("exportBtn");

    button.disabled = true;
    button.innerText = "正在导出...";

    const wasmModule = window.spirexls || window.xlswasm;

    try {

        // 获取 HTML 表格
        const tableHtml =
            document.getElementById("salesTable").outerHTML;

        // 移除内联样式
        const safeTableHtml =
            tableHtml.replace(/style="[^"]*"/g, '');

        const htmlContent = `
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
            </head>
            <body>
                ${safeTableHtml}
            </body>
            </html>
        `;

        const htmlFileName = "Table.html";

        window.dotnetRuntime.Module.FS.writeFile(
            htmlFileName,
            htmlContent
        );

        const workbook = new wasmModule.Workbook();

        workbook.LoadFromHtml(htmlFileName);

        const sheet = workbook.Worksheets.get(0);

        const lastRow = Number(sheet.LastRow);
        const lastCol = Number(sheet.LastColumn);

        const headerRow =
            sheet.Range.get_Item(1, 1, 1, lastCol);

        headerRow.BuiltInStyle =
            wasmModule.BuiltInStyles.Heading3;

        for (let i = 2; i <= lastRow; i++) {

            const row =
                sheet.Range.get_Item(i, 1, i, lastCol);

            row.BuiltInStyle =
                i % 2 === 0
                    ? wasmModule.BuiltInStyles.Accent3_20
                    : wasmModule.BuiltInStyles.Accent3_60;
        }

        for (let j = 1; j <= lastCol; j++) {
            sheet.AutoFitColumn(j);
        }

        const outputFileName = "SalesReport.xlsx";

        workbook.SaveToFile({
            fileName: outputFileName,
            version: wasmModule.ExcelVersion.Version2016
        });

        workbook.Dispose();

        const fileData =
            window.dotnetRuntime.Module.FS.readFile(outputFileName);

        const blob = new Blob([fileData], {
            type:
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        });

        const url = URL.createObjectURL(blob);

        const a = document.createElement("a");

        a.href = url;
        a.download = outputFileName;

        document.body.appendChild(a);
        a.click();

        document.body.removeChild(a);

        URL.revokeObjectURL(url);

    } catch (error) {

        alert("导出失败:" + error.message);

    } finally {

        button.disabled = false;
        button.innerText = "导出 Excel";
    }
}

以下截图展示导出前在浏览器中显示的基于 HTML 的销售报表表示例。

基于 HTML 的销售报表表格

导出后,生成的 Excel 工作簿保留了表格结构并应用了额外的 Excel 原生格式。

在 JavaScript 中将 HTML 表格导出为 Excel

为什么使用基于 HTML 的 Excel 导出

使用基于 HTML 的导出为现代 Web 应用程序提供了多项优势:

  • 重用现有的前端表格,无需重建电子表格布局
  • 减少重复的数据格式化和导出逻辑
  • 在导入 HTML 表格后应用 Excel 原生样式
  • 直接从仪表板页面导出业务报表

借助 Spire.XLS for JavaScript,可以快速将浏览器渲染的 HTML 表格转换为可下载的 Excel 文件,同时保持整个导出工作流程在客户端完成。


在 React 中使用 JavaScript 导出 Excel

将 Excel 导出功能集成到 React 应用程序中非常简单。关键是在渲染 React 组件之前初始化 WebAssembly 运行时,并在导出操作后正确释放工作簿资源。

在 React 中初始化 Spire.XLS

在创建导出组件之前,需要在应用程序入口文件(main.jsx 或 index.js)中初始化 WebAssembly 模块:

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';

// 在挂载 React 之前初始化 Spire.XLS
const initializeSpire = async () => {

    // 加载公共运行时
    const commonModule = await import(
        '/node_modules/spire.office/spire.common.js'
    );

    // 初始化 WebAssembly 运行时
    await commonModule.initializeWasm();

    // 加载 Spire.XLS 模块
    await import(
        '/node_modules/spire.office/spire.xls.js'
    );

    // 可选:如果需要预加载字体
    // await window.spire.FetchFileToVFS(
    //     'ARIAL.TTF',
    //     '/Library/Fonts/',
    //     '/'
    // );
};

// 初始化完成后启动 React 应用
initializeSpire().then(() => {

    createRoot(document.getElementById('root')).render(
        <StrictMode>
            <App />
        </StrictMode>
    );

});

然后在应用程序中使用下面的 React 导出组件。

简化的 React Excel 导出组件

以下是一个最小的 React 组件,演示了核心导出模式:

import { useState } from 'react'

const ExcelExportButton = () => {
    const [isProcessing, setIsProcessing] = useState(false);

    const handleExport = async () => {
        if ((!window.spirexls && !window.xlswasm) || isProcessing) return;

        setIsProcessing(true);
        const wasmModule = window.spirexls || window.xlswasm;

        try {
            // 创建新工作簿并获取第一个默认工作表
            const workbook = new wasmModule.Workbook();
            const worksheet = workbook.Worksheets.get(0);

            // 将数据插入工作表
            worksheet.Range.get("A1").Text = "产品";
            worksheet.Range.get("B1").Text = "收入";
            worksheet.Range.get("A2").Text = "笔记本电脑";
            worksheet.Range.get("B2").NumberValue = 9999.90;
            worksheet.Range.get("A3").Text = "智能手机";
            worksheet.Range.get("B3").NumberValue = 4999.99;

            const outputFileName = "Report.xlsx";

            // 将工作簿保存到 VFS 中的文件
            workbook.SaveToFile({
                fileName: outputFileName,
                version: wasmModule.ExcelVersion.Version2016
            });

            workbook.Dispose();

            const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);

            const excelBlob = new Blob([fileArray], {
                type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            });

            const url = URL.createObjectURL(excelBlob);

            const a = document.createElement('a');
            a.href = url;
            a.download = outputFileName;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);

            URL.revokeObjectURL(url);

        } catch (error) {
            console.error("Excel 导出失败:", error);
        } finally {
            setIsProcessing(false);
        }
    };

    return (
        <button onClick={handleExport} disabled={isProcessing}>
            {isProcessing ? "正在生成..." : "导出到 Excel"}
        </button>
    );
}

export default function App() {
    return (
        <div>
            <h1>Spire.XLS 演示</h1>
            <ExcelExportButton />
        </div>
    );
}

关键实现细节:

  • 最小化状态 – 仅跟踪 isProcessing 以在导出期间禁用按钮
  • 直接下载 – 立即触发下载,无需在状态中存储 URL
  • 资源清理 – 始终对工作簿对象调用 Dispose() 以防止内存泄漏
  • 错误处理 – 将导出逻辑包装在 try-catch 块中以实现健壮的错误管理
  • 加载状态 – 在处理期间禁用按钮以防止重复导出

在应用中使用:

import { ExcelExportButton } from './ExcelExportButton';

function App() {
    return (
        <div>
            <h1>销售仪表板</h1>
            <ExcelExportButton />
        </div>
    );
}

这种简化的方法专注于基本的导出流程,没有不必要的复杂性。对于更高级的场景(如加载外部文件或字体),请参考完整文档。

如需了解浏览器端文档分发工作流程,可以进一步探索 如何在 JavaScript 和 React 应用程序中将 Excel 文件转换为 PDF。


使用 JavaScript 无需后端生成 Excel 文件

现代 Web 应用程序越来越多地直接在浏览器中生成 Excel 文件,而不是依赖后端服务。借助 Spire.XLS for JavaScript,电子表格创建、格式化和导出操作完全使用 WebAssembly 在客户端运行。

为什么可以不需要后端服务器

传统的 Excel 导出工作流程通常需要服务器来:

  1. 接收前端数据
  2. 生成电子表格文件
  3. 返回可下载的文件给浏览器

使用基于 WebAssembly 的处理,这些步骤完全在浏览器运行时中进行。

客户端 Excel 导出的优势

与传统的服务器端导出工作流程相比,客户端 Excel 生成具有以下优势:

特性 浏览器端导出 服务器端导出
数据处理 在浏览器本地运行 需要后端服务器
隐私保护 数据保留在客户端设备上 数据通过网络发送
响应速度 即时本地处理 取决于网络延迟
基础设施成本 无需导出服务器 需要后端资源
离线支持 支持 通常不可用
可扩展性 由客户端设备处理 受服务器容量限制

工作原理

使用 Spire.XLS for JavaScript 时:

  1. WebAssembly 运行时在浏览器中加载
  2. 电子表格处理在内存中本地运行
  3. 文件暂时存储在浏览器虚拟文件系统 (VFS) 中
  4. JavaScript 将生成的文件转换为可下载的 Blob
  5. 浏览器直接触发下载

这种架构使得基于浏览器的 Excel 导出特别适用于仪表板、报表系统、内部业务工具和注重隐私的应用程序。


故障排除和最佳实践

在浏览器环境中使用 Spire.XLS for JavaScript 时,可能会遇到以下问题。

WASM 模块未初始化

如果 window.spirexls 或 window.xlswasm 未定义,请确保在使用 API 之前完全初始化 WebAssembly 运行时:

await commonModule.initializeWasm();
await import('/node_modules/spire.office/spire.xls.js');

缺少资源或 ZIP 加载错误

如果浏览器控制台显示 404 错误或 WebAssembly 加载失败:

  • 确保 ZIP 和 WASM 资源放置在正确的静态目录中
  • Vite 项目应将资产放置在 public/ 文件夹中
  • 验证浏览器是否可以成功加载 .zip 和 .wasm 文件

字体相关警告

某些环境可能会显示如下警告:

"Arial 字体未安装"

可以在创建工作簿之前预加载字体:

await window.spire.FetchFileToVFS(
    'ARIAL.TTF',
    '/Library/Fonts/',
    '/'
);

无效或损坏的 XLSX 文件

如果 Excel 打开时显示修复警告,请在导出时明确指定 Excel 版本:

workbook.SaveToFile({
    fileName: outputFileName,
    version: wasmModule.ExcelVersion.Version2016
});

内存管理

导出后务必释放工作簿资源,以避免长时间运行的应用程序中出现内存泄漏:

const workbook = new wasmModule.Workbook();

try {
    // Excel 操作
} finally {
    workbook.Dispose();
}

浏览器端性能考虑

对于非常大的数据集,浏览器端处理可能会变得缓慢或占用大量内存。在这种情况下:

  • 在导出期间显示加载指示器
  • 避免在单个操作中导出极大数据集
  • 考虑为企业级报表使用服务器端处理

总结

Spire.XLS for JavaScript 提供了一种实用的方法,可以使用 JavaScript 和 WebAssembly 在现代 Web 应用程序中直接生成和导出 Excel 文件。其基于浏览器的架构使其适用于仪表板、报表系统以及需要在不依赖后端服务的情况下生成可下载电子表格的前端应用程序。

本文中的示例演示了如何使用 JavaScript、React 和 WebAssembly 构建基于浏览器的 Excel 导出工作流程,同时将电子表格处理完全保持在客户端。可以 申请 30 天免费许可证 在购买前评估所有功能。


常见问题

Q1:是否可以在没有后端服务器的情况下使用 JavaScript 下载 Excel 文件?

A1:可以。Spire.XLS for JavaScript 使用 WebAssembly 技术完全在浏览器中生成和下载 Excel 文件。工作簿在浏览器内存中创建并直接下载,无需任何后端 API 或服务器端处理。

Q2:如何在 JavaScript 中将 HTML 表格导出为 Excel?

A2:可以从 DOM 中提取现有的 HTML 表格,将 HTML 写入 WebAssembly 虚拟文件系统,并使用 LoadFromHtml() 将其加载到工作簿中。这种方法允许重用浏览器渲染的表格,而无需手动重建电子表格布局。

Q3:是否可以在 React 应用程序中使用 Spire.XLS for JavaScript?

A3:可以。Spire.XLS for JavaScript 可与 React、Vite 和其他现代前端框架配合使用。只需要在渲染组件之前初始化 WebAssembly 模块,然后直接在 React 组件或实用函数中执行 Excel 操作。

Q4:为什么 Excel 在打开导出的文件时显示修复警告?

A4:这通常发生在导出时未明确指定 Excel 版本的情况下。为避免兼容性问题,请在调用 SaveToFile() 时指定输出版本:

workbook.SaveToFile({
    fileName: outputFileName,
    version: wasmModule.ExcelVersion.Version2016
});

Spire.XLS教你用C#将CSV转换为XML

CSV 与 XML 是软件开发中最常用的两大数据交换格式:CSV 轻量化、适合存储传输表格数据;XML 具备层级结构与严格校验规则,广泛用于跨系统对接、接口交互。在配置文件生成、数据库数据导出、第三方 API 对接等业务场景中,CSV 转 XML 是高频开发需求。

手动解析 CSV 拼接 XML 不仅代码冗余、极易出错,处理大批量数据时效率极低。而 Spire.XLS for .NET 作为独立高性能 Excel 组件,无需依赖 Office,可快速实现 C# 中 CSV 到 XML 的高效转换。本文将详细介绍两种主流转换方案,并附带完整代码示例。


环境前置准备

通过 NuGet 安装 Spire.XLS

在 Visual Studio 中打开 “程序包管理器控制台” 执行以下命令:

Install-Package Spire.XLS

或者在 NuGet 可视化界面中搜索 “Spire.XLS”,安装最新稳定版即可。

准备测试 CSV 文件

在项目输出目录中创建一个 Products.csv 文件,写入以下表格数据(包含表头和数据行):

商品ID,商品名称,商品分类,单价,库存数量,上架日期
1,笔记本电脑,电子产品,999.99,50,2023-01-15
2,无线鼠标,电子产品,25.50,200,2023-02-20
3,纯棉T恤,服饰,19.99,150,2022-11-05
4,咖啡马克杯,家居用品,12.99,300,2022-09-10
5,办公椅,家具,150.00,75,2023-03-01

两种 XML 输出格式说明

使用 Spire.XLS 转换 CSV 时,支持生成两种主流 XML 格式,可按需选择:

1. Excel XML(SpreadsheetML)

基于微软 Open XML 规范的官方格式,完整保留 CSV 的表格布局、单元格样式与数据结构。

  • 适用场景:需用 Excel、WPS 等表格工具直接打开编辑 XML 文件。

2. 自定义结构 XML

开发者可自定义根节点、子节点、层级关系,自由映射 CSV 列与 XML 标签。

  • 适用场景:对接第三方接口、老旧业务系统、有固定 XML 报文规范的业务场景。

Python 开发者可参考专属教程:使用 Python 将 CSV 转换为 XML(处理现实数据问题)


方法一:使用 C# 将 CSV 转换为 Excel XML

这是最简单的实现方式,仅需几行代码即可完成。将 CSV 加载到 Workbook(工作簿)实例中,然后直接另存为 Excel XML(SpreadsheetML)格式。适用于目标系统支持 Excel 原生 XML 格式的场景。

CSV 转 XML C# 代码示例:

using Spire.Xls;

namespace CsvToExcelXmlConverter
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建工作簿实例
            Workbook workbook = new Workbook();

            // 将CSV加载到第一个工作表
            workbook.LoadFromFile("Products.csv", ",", 1, 1);

            // 另存为SpreadsheetML格式
            workbook.SaveAsXml("output.xml");

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

核心方法解析:

  • LoadFromFile():自动解析 CSV 数据,导入到工作簿首个工作表,完美兼容中文编码;
  • SaveAsXml():一键将表格数据导出为标准 SpreadsheetML 格式,中文无乱码。

核心数据部分的效果如下:

使用C#和Spire.XLS将CSV转换为SpreadsheetML

拓展:该组件同样支持 Excel XLS/XLSX 转 XML,复用同一套 SaveAsXml 方法。


方法二:使用 C# 将 CSV 转为自定义结构 XML

当目标系统要求特定的 XML 架构时,就需要构建自定义 XML 文档。Spire.XLS 结合 .NET 内置的 XmlWriter 类即可轻松遍历表格行列,自由定制根节点、数据节点与标签名称,中文表头自动映射为 XML 节点名,无乱码。

自定义 XML 代码示例:

using Spire.Xls;
using System.Xml;

namespace CSVtoXMLConverter
{
    class Program
    {
        static void Main(string[] args)
        {
            // 初始化工作簿并加载CSV
            Workbook workbook = new Workbook();
            workbook.LoadFromFile("Products.csv", ",", 1, 1);
            Worksheet worksheet = workbook.Worksheets[0];

            // 创建自定义XML设置(缩进优化可读性)
            XmlWriterSettings settings = new XmlWriterSettings
            {
                Indent = true,
                IndentChars = "\t",
                OmitXmlDeclaration = false,
                Encoding = System.Text.Encoding.UTF8
            };

            // 将CSV保存为带自定义根节点和格式的XML
            XmlWriter writer = XmlWriter.Create("Custom_Output.xml", settings);

            writer.WriteStartDocument();
            // 自定义根元素:<ProductInventory>
            writer.WriteStartElement("ProductInventory");

            // 遍历CSV行(跳过表头行:从第2行开始)
            for (int row = 2; row <= worksheet.LastRow; row++)
            {
                // 自定义数据节点:<Product>
                writer.WriteStartElement("Product");

                // 遍历CSV列并写入自定义元素
                for (int col = 1; col <= worksheet.LastColumn; col++)
                {
                    string header = worksheet.Range[1, col].Text;
                    string value = worksheet.Range[row, col].Text;
                    writer.WriteElementString(header, value);
                }

                writer.WriteEndElement(); // 闭合<Product>节点
            }

            writer.WriteEndElement(); // 闭合<ProductInventory>节点
            writer.WriteEndDocument();

            writer.Close();
            workbook.Dispose();
        }
    }
}

实现逻辑

  1. 加载 CSV 并获取工作表数据,自动适配中文编码;
  2. 配置 XmlWriter 缩进、UTF8 编码,从根源避免中文乱码;
  3. 自定义中文根节点与数据节点,循环行列自动生成 XML 标签,中文表头直接映射为节点名;
  4. 自动闭合节点、释放资源,生成规范自定义 XML。

输出效果:

生成的 XML 以 <ProductInventory> 为根节点、<Product> 为数据节点,子节点名称与 CSV 表头一致,完全匹配自定义业务需求。

使用C#和Spire.XLS将CSV转换为自定义XML结构


适配真实业务 CSV 特殊场景

实际项目中 CSV 常存在非标准分隔符、空值、无表头、冗余行列等问题,以下为通用解决方案:

1. 适配多种自定义分隔符

CSV文件可能使用制表符(\t)、分号(;)或竖线(|)作为分隔符。Spire.XLS 支持加载 CSV 时指定自定义分隔符:

// 制表符分隔
workbook.LoadFromFile("data.tsv", "\t", 1, 1);

// 分号分隔(欧洲地区常用)
workbook.LoadFromFile("data.csv", ";", 1, 1);

// 竖线分隔
workbook.LoadFromFile("data.psv", "|", 1, 1);

2. 跳过指定行/列

如果 CSV 包含元数据行或空列,可调整循环边界:

// 从第3行开始遍历
for (int row = 3; row <= worksheet.LastRow; row++)
// 从第3列开始遍历
for (int col = 3; col <= worksheet.LastColumn; col++)

3. 处理空单元格与缺失值

CSV 中的空单元格会显示为空字符串,你可以通过填充默认值或忽略空元素来处理:

// 方案1:为空值填充"N/A"
string value = worksheet.Range[row, col].Text;
if (string.IsNullOrEmpty(value))
    value = "N/A";   
writer.WriteElementString(header, value);

// 方案2:忽略空节点
string value = worksheet.Range[row, col].Text;
if (!string.IsNullOrEmpty(value))
    writer.WriteElementString(header, value);

4. 缺失表头行

如果 CSV 没有表头行,可以传入自定义名称数组,或生成通用列名(示例如下):

for (int col = 1; col <= worksheet.LastColumn; col++)
{
    string header = $"列{col}"; // 生成列 1、列 2...
    string value = worksheet.Range[row, col].Text;
    writer.WriteElementString(header, value);
}

总结

借助 Spire.XLS for .NET 实现 C# CSV 转 XML,无需手动解析文本、无需安装 Office 依赖,大幅降低开发成本:

  • 简单场景:一行代码导出 Excel 标准 XML,开箱即用,完美兼容中文;
  • 定制场景:自由设计 XML 层级与节点,适配各类接口报文,中文无乱码;
  • 兼容复杂 CSV:支持多分隔符、空值、无表头、冗余行列等业务异常。

更多 Excel、CSV 批量处理教程,可查阅官方在线文档。


CSV 转 XML 常见问题解答

Q1:能否只转换指定单元格区域(如A1:C10)?

可以。无需遍历到 worksheet.LastRow 和 LastColumn,只需设置自定义边界,或直接通过 worksheet.Range 访问指定区域。

Q2:Spire.XLS 是否需要安装 Microsoft Excel?

不需要。它是独立的 .NET 组件,不依赖 Microsoft Excel、Office Interop 或任何第三方办公软件。

Q3:能否批量转换多个 CSV文件?

可以。遍历文件夹下所有 .csv 文件,循环调用本文转换逻辑,即可批量导出对应 XML。

Q4:可以给 XML 节点添加自定义属性和命名空间吗?

可以。通过 XmlWriter.WriteAttributeString() 添加节点属性,也可在创建元素时指定命名空间,满足企业级 XML 规范要求。

我们很高兴地宣布 Spire.OfficeJS 11.5.7 正式发布。本次更新新增了 Linux(Arm64)部署包,为现代服务器环境提供了更广泛的平台兼容性。此外,Spire.OfficeJS 现已支持移动设备打开文档,并可通过 “coAuthorUrl” 配置实现协同编辑功能。这些增强进一步提升了 Spire.OfficeJS 在在线 Office 应用中的灵活性与易用性。更多详情如下。

新功能:


获取 Spire.OfficeJS 11.5.7,请点击:

https://www.e-iceblue.cn/Downloads/Spire-OfficeJS.html

Spire.Office for Java 11.5.0 已正式发布。本版本中,Spire.PDF for Java 新增支持 PDF 转换进度回调功能;Spire.Doc for Java 新增支持脚注/尾注计数以及字体嵌入选项;Spire.Presentation for Java 新增支持图片压缩功能。此外,本版本还成功修复了多个问题。更多详情如下。


获取 Spire.Office for Java 11.5.0,请点击:

https://www.e-iceblue.cn/Downloads/Spire-Office-JAVA.html

Spire.Doc for Java

新功能:

问题修复:

Spire.PDF for Java

新功能:

问题修复:

Spire.Presentation for Java

新功能:

问题修复:

Spire.Doc 14.5.14 现已发布。该版本增强了 Word 到 PDF 的转换功能,并修复了多个问题,包括排版不一致、字体效果异常以及文档处理过程中出现的多种异常问题。详情如下。

问题修复:


获取 Spire.Doc 14.5.14,请点击:

https://www.e-iceblue.cn/Downloads/Spire-Doc-NET.html