我们很高兴地宣布 Spire.PDF 12.6.5 正式发布。本次更新主要修复了 XPS 转 PDF 以及 PDF 转 PDF/X 过程中出现的问题。详细更新内容如下。
调整:
| 旧类名 | 新类名 | 旧属性名 | 新属性名 |
|---|---|---|---|
| PdfLaunchAction | PdfLaunchAction | IsNewWindow | NewWindow |
| PdfActionDestination | PdfPredefinedAction | ||
| PdfEmbeddedGoToAction | PdfEmbeddedGoToAction | IsNewWindow | NewWindow |
| PdfResetAction | PdfResetFormAction | ||
| PdfSubmitAction | PdfSubmitFormAction | ||
| PdfUriAction | PdfURIAction | Uri | URI |
| PdfFieldActions | PdfFormFieldAdditionalActions | ||
| PdfAnnotationActions | PdfAnnotationAdditionalActions | MouseEnter | OnEnter |
| MouseLeave | OnExit | ||
| MouseDown | OnMouseDown | ||
| MouseUp | OnMouseUp | ||
| GotFocus | OnReceiveFocus | ||
| LostFocus | OnLostFocus | ||
| Calculate | / | ||
| Validate | / | ||
| KeyPressed | / | ||
| Format | / | ||
| PdfDocumentActions | PdfDocumentAdditionalActions | Calculate | OnCalculate |
| Validate | OnValidate | ||
| KeyPressed | OnModifyCharacter | ||
| Format | OnFormat | ||
| MouseEnter | OnEnter | ||
| MouseLeave | OnExit | ||
| MouseDown | OnMouseDown | ||
| MouseUp | OnMouseUp | ||
| GotFocus | OnReceiveFocus | ||
| LostFocus | OnLostFocus |
| 旧类名 (Spire.Pdf.General命名空间) |
新类名 (Spire.Pdf.Destinations命名空间) |
旧属性名 | 新属性名 |
|---|---|---|---|
| PdfDestination | PdfDestination, PdfExplicitDestination |
||
| PdfDestination (Mode=Location) |
PdfXYZExplicitDestination | Location | Left, Top |
| Rectangle | / | ||
| Mode | Type | ||
| PdfDestination (Mode=FitToPage) |
PdfFitExplicitDestination | Location | / |
| Rectangle | / | ||
| Zoom | / | ||
| Mode | Type | ||
| PdfDestination (Mode=FitH) |
PdfFitHExplicitDestination | Location | Top |
| Rectangle | / | ||
| Zoom | / | ||
| Mode | Type | ||
| PdfDestination (Mode=FitR) |
PdfFitRExplicitDestination | Location | / |
| Rectangle | Left,Bottom, Right, Top | ||
| Zoom | / | ||
| Mode | Type | ||
| PdfDestination (Mode=FitV) |
PdfFitVExplicitDestination | Location | Left |
| Rectangle | / | ||
| Zoom | / | ||
| Mode | Type | ||
| PdfFitBExplicitDestination | |||
| PdfFitBVExplicitDestination | / | Left |
问题修复:

XML 是一种广泛使用的结构化数据存储格式,但对于数据分析或 Excel 等表格工具而言并不够友好。将 XML 转换为 CSV 可以将数据整理成更简单的二维表格格式,这种格式兼容电子表格和数据分析库。通过将 XML 转换为 CSV,你可以轻松地将数据导入 Excel、执行计算,或将其作为输入数据提供给 Pandas 等 Python 数据分析工具。
这种方法还有助于将复杂的层级数据标准化为更易于阅读、处理和共享的格式。在本教程中,我们将探讨如何使用 Spire.XLS for Python 高效地将 XML 文件转换为 CSV。
开始之前,需要先安装 Spire.XLS。该库已发布到 PyPI,可直接使用 pip 安装:
pip install spire.xls
安装完成后,导入所需类:
from spire.xls import *
from spire.xls.common import *
Spire.XLS 提供了 Workbook 和 Worksheet 对象,用于管理类似 Excel 的工作簿和工作表。后续我们将利用它们创建 CSV 文件并写入 XML 数据。
XML 文件采用树状层级结构组织数据,其中元素(节点)由标签包裹。每个元素可以包含文本内容、属性以及其他子元素。
例如下面的 Books.xml:
<catalog>
<book isbn="9787020002207">
<title>红楼梦</title>
<author>曹雪芹</author>
<year>1791</year>
<genre>古典文学</genre>
<price>68.00</price>
<reviews>
<review>中国古典文学的巅峰之作</review>
</reviews>
</book>
<book isbn="9787506365437">
<title>三体</title>
<author>刘慈欣</author>
<year>2008</year>
<genre>科幻</genre>
</book>
</catalog>
XML 转 CSV 面临的挑战:
因此,一个可靠的转换程序必须能够将 XML 的层级结构映射到 CSV 的表格结构中。
要在 Python 中加载并解析 XML 文件,可以使用 内置的 xml.etree.ElementTree 库。该库可以用于解析 XML 文件。
示例:
import xml.etree.ElementTree as ET
# 加载 XML 文件
tree = ET.parse("Books.xml")
root = tree.getroot()
# 遍历书籍节点
for book in root.findall("book"):
title = book.findtext("title", "")
author = book.findtext("author", "")
isbn = book.attrib.get("isbn", "")
完成数据提取后,就可以利用 Spire.XLS for Python 创建工作簿并导出 CSV 文件。
在 Python 中将 XML 转换为 CSV 的基本流程:
让我们从一个基础的 XML 到 CSV 转换开始。下面的示例会自动读取第一个 <book> 元素生成表头,然后将所有子节点导出到 CSV 中。
from spire.xls import *
from spire.xls.common import *
import xml.etree.ElementTree as ET
# 创建 Workbook
workbook = Workbook()
# 删除默认工作表
workbook.Worksheets.Clear()
# 添加工作表
worksheet = workbook.Worksheets.Add("Books")
# 加载 XML 文件
xml_tree = ET.parse("C:\\Users\\Administrator\\Desktop\\Books.xml")
xml_root = xml_tree.getroot()
# 获取第一个 book 节点
first_book = xml_root.find("book")
# 提取表头
header = list(first_book.iter())[1:]
# 定义英文和中文标签的映射关系
label_mapping = {
"title": "书名",
"author": "作者",
"year": "年份",
"genre": "类型",
}
# 写入表头
for col_index, header_node in enumerate(header, start=1):
en_tag = header_node.tag
cn_tag = label_mapping.get(en_tag, en_tag)
worksheet.SetValue(1, col_index, cn_tag)
# 写入数据
row_index = 2
for book in xml_root.iter("book"):
for col_index, data_node in enumerate(list(book.iter())[1:], start=1):
worksheet.SetValue(row_index, col_index, data_node.text)
row_index += 1
# 保存 CSV
worksheet.SaveToFile("output/XmlToCsv.csv", ",", Encoding.get_UTF8())
# 释放资源
workbook.Dispose()
该脚本适用于结构简单的 XML 文件,可自动生成表头(书名、作者、年份、类型),并写入对应数据。
输出:

你可能还会感兴趣: 在 Python 中将 XML 转换为 Excel 和 PDF
基础脚本在许多情况下都适用,但 XML 往往并非如此简单。下面介绍一些处理实际场景的高级技巧。
有时 XML 中包含大量数据,但你只需要部分字段。
例如,仅导出书名和作者:
from spire.xls import *
from spire.xls.common import *
import xml.etree.ElementTree as ET
# 创建 Workbook 对象
workbook = Workbook()
# 移除默认工作表
workbook.Worksheets.Clear()
# 添加工作表并命名
worksheet = workbook.Worksheets.Add("Books")
# 加载 XML 文件
xml_tree = ET.parse(r"C:\Users\Administrator\Desktop\Books.xml")
xml_root = xml_tree.getroot()
# 定义想要导出的元素
selected_elements = ["title", "author"]
# 定义英文和中文标签的映射关系
label_mapping = {
"title": "书名",
"author": "作者",
}
# 写入表头
for col_index, tag in enumerate(selected_elements, start=1):
cn_tag = label_mapping.get(tag, tag)
worksheet.SetValue(1, col_index, cn_tag)
# 写入数据
row_index = 2
for book in xml_root.iter("book"):
for col_index, tag in enumerate(selected_elements, start=1):
# 使用 findtext 安全地处理缺失值
worksheet.SetValue(row_index, col_index, book.findtext(tag, ""))
row_index += 1
# 保存 CSV
worksheet.SaveToFile("output/XmlToCsv_Selected.csv", ",", Encoding.get_UTF8())
# 释放资源
workbook.Dispose()
这样导出的 CSV 仅包含所需列。
输出:

如果重要数据存储在属性中(例如 ISBN),也可以轻松导出。
from spire.xls import *
from spire.xls.common import *
import xml.etree.ElementTree as ET
# 创建 Workbook 对象
workbook = Workbook()
# 移除默认工作表
workbook.Worksheets.Clear()
# 添加工作表并命名
worksheet = workbook.Worksheets.Add("Books")
# 加载 XML 文件
xml_tree = ET.parse(r"C:\Users\Administrator\Desktop\Books.xml")
# 获取 XML 树的根元素
xml_root = xml_tree.getroot()
# 获取第一个 book 元素
first_book = xml_root.find("book")
# 提取表头信息(子节点)
header = list(first_book.iter())[1:]
# 定义英文和中文标签的映射关系
label_mapping = {
"isbn": "ISBN编号",
"title": "书名",
"author": "作者",
"year": "年份",
"genre": "类型",
}
# 将表头写入 Excel
cn_isbn = label_mapping.get("isbn", "isbn")
worksheet.SetValue(1, 1, cn_isbn) # <-- 首先添加 ISBN 列
for col_index, header_node in enumerate(header, start=2): # 现在从第 2 列开始
en_tag = header_node.tag
cn_tag = label_mapping.get(en_tag, en_tag)
worksheet.SetValue(1, col_index, cn_tag)
# 写入数据
row_index = 2
for book in xml_root.iter("book"):
# 将 isbn 作为文本写入
isbn_value = book.attrib.get("isbn", "")
worksheet.Range[row_index, 1].Text = isbn_value
# 然后写入其他字段
for col_index, data_node in enumerate(list(book.iter())[1:], start=2):
value = data_node.text
worksheet.SetValue(row_index, col_index, value)
row_index += 1
# 将整个 ISBN 列格式化为文本,以防止出现科学记数法
last_row = row_index - 1
isbn_range = f"A2:A{last_row}"
worksheet.Range[isbn_range].NumberFormat = "@"
# 保存 CSV
worksheet.SaveToFile("output/XmlToCsv_WithAttributes.csv", ",", Encoding.get_UTF8())
# 释放资源
workbook.Dispose()
这里显式地创建了一个 ISBN 列,从每个 <book> 的属性中提取它,并将其格式化为文本,以防止 Excel 以科学记数法显示它。
输出:

假设 XML 如下:
<catalog>
<book>
<title>活着</title>
<author>余华</author>
<reviews>
<review>一部震撼人心的作品</review>
<review>读了好几遍仍然感动</review>
<review>让人重新思考生命的意义</review>
</reviews>
</book>
</catalog>
CSV 无法直接表示多层嵌套结构,因此可以将多个 <review> 条目合并到单个 CSV 列中:
from spire.xls import *
from spire.xls.common import *
import xml.etree.ElementTree as ET
# 创建 Workbook 对象
workbook = Workbook()
# 移除默认工作表
workbook.Worksheets.Clear()
# 添加工作表并命名
worksheet = workbook.Worksheets.Add("Books")
# 加载 XML 文件
xml_tree = ET.parse(r"C:\Users\Administrator\Desktop\Nested.xml")
xml_root = xml_tree.getroot()
# 获取第一个 <book> 元素
first_book = xml_root.find("book")
# 收集表头(自动检测)
header = []
for child in first_book:
if child.tag == "reviews":
header.append("reviews") # 将嵌套的 <review> 合并到一个列中
else:
header.append(child.tag)
# 定义英文和中文标签的映射关系
label_mapping = {
"title": "书名",
"author": "作者",
"year": "年份",
"genre": "类型",
"price": "价格",
"reviews": "评论",
}
# 写入表头行
for col_index, header_text in enumerate(header, start=1):
cn_header = label_mapping.get(header_text, header_text)
worksheet.SetValue(1, col_index, cn_header)
# 写入数据行
row_index = 2
for book in xml_root.iter("book"):
col_index = 1
for child in book:
if child.tag == "reviews":
# 将所有 <review> 的文本合并到一个单元格中
reviews = [r.text for r in child.findall("review") if r.text]
worksheet.SetValue(row_index, col_index, "; ".join(reviews))
else:
worksheet.SetValue(row_index, col_index, child.text if child.text else "")
col_index += 1
row_index += 1
# 保存 CSV
worksheet.SaveToFile("output/XmlToCsv_WithReviews.csv", ",", Encoding.get_UTF8())
# 释放资源
workbook.Dispose()
输出:

Spire.XLS 不仅支持将数据从标准 XML 文件导入 Excel 或 CSV,还允许将 OpenXML(Microsoft 的基于 XML 的文件格式)转换为 Excel。如果你感兴趣,可以查看这篇教程:如何在 Python 中将 Excel 转换为 OpenXML 以及将 OpenXML 转换为 Excel。
即使脚本结构良好,在将 XML 转换为 CSV 时也可能遇到一些常见问题:
1. Excel 显示科学计数法
worksheet.Range["A2:A{last_row}"].NumberFormat = "@"
2. 缺失字段导致报错
3. 表头不完整
4. 编码问题
worksheet.SaveToFile("output.csv",",", Encoding.get_UTF8())
在 Python 中将 XML 转换为 CSV 并不复杂。借助 Spire.XLS for Python,你可以自动完成大部分过程,包括表头生成、处理属性以及展平嵌套节点。无论是简单 XML、复杂层级结构,还是包含大量属性的数据集,都可以通过上述方法轻松转换为便于分析的 CSV 格式。
答:可以。只需使用 workbook.SaveToFile("output.xlsx", ExcelVersion.Version2016) 即可。
答:使用 Python 的 xml.etree.ElementTree 中的 iterparse() 来流式处理大文件,避免一次性加载到内存中。
答:可以在生成表头前扫描所有 <book> 节点,动态收集所有唯一标签。
答:可以。在调用 SaveToFile() 时,替换分隔符参数即可:
worksheet.SaveToFile("output.csv", ";", Encoding.get_UTF8())
答:通过合并值将它们展平到单个单元格。例如:
reviews = [r.text for r in book.find("reviews").findall("review")]
worksheet.SetValue(row_index, col_index, "; ".join(reviews))
如果希望在没有评估版限制的情况下体验 Spire.XLS for Python 的全部功能,可以申请免费的 30 天试用许可证。
Spire.Doc 14.6.9 现已正式发布。该版本优化了修订功能,部分接受修订效果有所改善,并修复了接受修订后转换Word到PDF结果不正确的问题。详情如下。
优化:
问题修复:

格式化在提升 Excel 电子表格的可读性、分析性和展示效果方面发挥着重要作用。无论您是在生成报表、发票、财务报表还是仪表板,原始数据在分享给最终用户之前,通常都需要经过适当的样式设置。
在 C# 中,Excel 格式化任务可能包括更改字体、应用颜色、对齐内容、设置数字和日期格式、添加边框、创建表格以及配置页面布局。手动执行这些任务可能非常耗时,尤其是在处理大量电子表格时。
Spire.XLS for .NET 提供了一套全面的 API,可在无需安装 Microsoft Excel 的情况下创建、编辑、格式化和转换 Excel 文档。在本文中,您将学习如何使用 Spire.XLS for .NET 在 C# 中 对 Excel 文件应用各种类型的格式设置 。
目录:
Spire.XLS for .NET 是一个强大的 Excel 库,使开发人员能够以编程方式处理 XLS、XLSX、XLSM、CSV 以及其他电子表格格式。除格式化操作外,它还支持公式计算、图表创建、数据透视表、工作表管理、打印以及文件转换。
要安装 Spire.XLS for .NET,请运行以下 NuGet 命令:
Install-Package Spire.XLS
在应用格式之前,加载现有的 Excel 工作簿(或创建一个新工作簿),并获取要修改的工作表。完成所有格式化操作后,使用 SaveToFile() 方法将结果保存为新的 Excel 文件。
using Spire.Xls;
using System.Drawing;
// Create a workbook object
Workbook workbook = new Workbook();
// Load an existing Excel file
workbook.LoadFromFile("input.xlsx");
// Get a specific worksheet
Worksheet sheet = workbook.Worksheets[0];
// Apply formatting
...
// Save the result
workbook.SaveToFile("output.xlsx", ExcelVersion.Version2016);
注意: 以下示例假设工作簿已经加载,并且已获取工作表对象。
单元格外观设置决定了数据在工作表中的显示方式。适当的格式设置可以显著提高可读性,并帮助用户快速识别重要信息。
字体格式允许您自定义单元格内容的视觉样式。常见选项包括字体名称、字体大小、加粗、斜体、下划线和字体颜色。这些设置通常用于报表标题、章节标题和重点数据。
CellStyle style = workbook.Styles.Add("FontStyle");
style.Font.FontName = "Calibri";
style.Font.Size = 14;
style.Font.IsBold = true;
style.Font.IsItalic = true;
style.Font.Underline = FontUnderlineType.Single;
style.Font.Color = Color.Blue;
sheet.Range["A1"].Text = "Formatted Text";
sheet.Range["A1"].Style = style;
背景颜色有助于区分工作表中的不同区域,并突出显示关键单元格。例如,您可以为标题行设置颜色,或者使用对比色填充汇总数据。
sheet.Range["A2"].Text = "Background Color";
sheet.Range["A2"].Style.Color = Color.LightSkyBlue;
Excel 提供水平对齐、垂直对齐、缩进和文本旋转等选项。合理的对齐方式能够改善工作表整体布局,使表格数据更易于浏览。
sheet.Range["B2"].Text = "Centered Text";
CellStyle style = sheet.Range["B2"].Style;
style.HorizontalAlignment = HorizontalAlignType.Center;
style.VerticalAlignment = VerticalAlignType.Center;
style.Rotation = 45;
sheet.SetRowHeight(2, 40);
sheet.SetColumnWidth(2, 20);
边框有助于分隔行和列,并定义表格结构。根据不同场景,您可以为单个单元格或整个区域添加边框,并自定义其样式和颜色。
CellRange range = sheet.Range["A4:D6"];
range.Text = "Border";
range.Style.Borders[BordersLineType.EdgeTop].LineStyle = LineStyleType.Thin;
range.Style.Borders[BordersLineType.EdgeBottom].LineStyle = LineStyleType.Thin;
range.Style.Borders[BordersLineType.EdgeLeft].LineStyle = LineStyleType.Thin;
range.Style.Borders[BordersLineType.EdgeRight].LineStyle = LineStyleType.Thin;
range.Style.Borders[BordersLineType.EdgeTop].Color = Color.Black;
当单元格内容超出列宽时,启用自动换行可在同一个单元格中显示多行内容,避免重要信息被截断。
sheet.Range["A8"].Text = "This is a very long sentence that will automatically wrap within the cell.";
sheet.Range["A8"].Style.WrapText = true;
sheet.SetColumnWidth(1, 20);
sheet.SetRowHeight(8, 60);
值格式设置仅改变数据的显示方式,而不会修改底层数据。这对于业务和财务电子表格尤为重要。
数字格式可控制小数位数、千位分隔符、科学计数法等显示规则。选择合适的格式有助于提高数据的准确性和可读性。
sheet.Range["A10"].NumberValue = 1234567.891;
sheet.Range["A10"].NumberFormat = "#,##0.00";
货币格式可根据需求自动显示货币符号和小数精度。这种格式常用于发票、预算和财务报表。
sheet.Range["A11"].NumberValue = 5999.95;
sheet.Range["A11"].NumberFormat = "$#,##0.00";
日期格式允许同一个日期值以不同样式显示,例如短日期、长日期或自定义格式。统一的日期格式使报表更易于理解。
sheet.Range["A12"].DateTimeValue = DateTime.Now;
sheet.Range["A12"].NumberFormat = "yyyy-MM-dd";
与逐个单元格设置格式相比,对较大的工作表区域应用格式可以提高效率并保持一致性。
一个区域可能包含多行和多列。将格式应用于区域可确保所有单元格具有一致的外观,并减少重复代码。
CellRange range = sheet.Range["A14:D18"];
range.Style.Color = Color.LightYellow;
range.Style.Font.IsBold = true;
range.Style.HorizontalAlignment = HorizontalAlignType.Center;
合并单元格通常用于报表标题和章节标题。合并后,可对内容进行居中和样式设置,以获得更专业的效果。
sheet.Range["A20:D20"].Merge();
sheet.Range["A20"].Text = "Monthly Sales Report";
sheet.Range["A20"].Style.Font.Size = 18;
sheet.Range["A20"].Style.Font.IsBold = true;
sheet.Range["A20"].Style.HorizontalAlignment = HorizontalAlignType.Center;
当特定区域中的所有单元格都需要采用相同样式时,对整行或整列进行格式设置非常有用,例如标题行或货币列。
sheet.Rows[21].Style.Font.IsBold = true;
sheet.Rows[21].Style.Color = Color.LightGray;
sheet.Columns[1].Style.NumberFormat = "$#,##0.00";
AutoFit 会根据单元格内容自动调整行高和列宽。这有助于避免文本被截断,并提升生成的电子表格的展示效果。
sheet.AllocatedRange.AutoFitColumns();
sheet.AllocatedRange.AutoFitRows();
条件格式允许 Excel 根据单元格值自动应用样式。无需手动突出显示数据,即可通过规则识别趋势、异常或重要数值。
例如,您可以高亮显示超过阈值的数字、显示数据条、应用颜色刻度,或使用图标集来可视化绩效指标。这些功能使大型数据集更易于分析和理解。
sheet.Range["A25"].NumberValue = 1200;
sheet.Range["A26"].NumberValue = 800;
sheet.Range["A27"].NumberValue = 1500;
XlsConditionalFormats formats = sheet.ConditionalFormats.Add();
formats.AddRange(sheet.Range["A25:A27"]);
IConditionalFormat format = formats.AddCondition();
format.FormatType = ConditionalFormatType.CellValue;
format.FirstFormula = "1000";
format.Operator = ComparisonOperatorType.Greater;
format.BackColor = Color.LightGreen;
格式设置也可以应用于工作表级别,以改善整个工作簿的结构和外观。
Excel 表格提供内置样式选项,例如标题格式、隔行颜色以及预定义主题。将数据区域转换为表格可以立即提升可读性和组织性。
sheet.Range["A30"].Text = "Product";
sheet.Range["B30"].Text = "Sales";
sheet.Range["A31"].Text = "Laptop";
sheet.Range["B31"].NumberValue = 5000;
sheet.Range["A32"].Text = "Monitor";
sheet.Range["B32"].NumberValue = 2000;
IListObject table = sheet.ListObjects.Create("SalesTable", sheet.Range["A30:B32"]);
table.BuiltInTableStyle = TableBuiltInStyles.TableStyleMedium2;
页面布局设置决定了工作表在打印或导出时的显示效果。常见选项包括页面方向、页边距、打印区域、缩放比例以及重复标题行。
适当的页面设置可确保报表在屏幕和纸张上都呈现专业效果。
sheet.PageSetup.Orientation = PageOrientationType.Landscape;
sheet.PageSetup.LeftMargin = 0.5;
sheet.PageSetup.RightMargin = 0.5;
sheet.PageSetup.TopMargin = 0.75;
sheet.PageSetup.BottomMargin = 0.75;
sheet.PageSetup.FitToPagesWide = 1;
sheet.PageSetup.FitToPagesTall = 1;
在实际场景中,通常会组合使用多种格式设置技术。一个典型报表可能包括合并标题、自定义字体、彩色表头、边框、数字格式、条件格式以及优化后的页面设置。
通过结合这些功能,您可以生成无需手动编辑即可直接分发的精美 Excel 文档。
using Spire.Xls;
using Spire.Xls.Core.Spreadsheet.Collections;
using Spire.Xls.Core;
using System.Drawing;
class Program
{
static void Main()
{
// 创建新的工作簿
Workbook workbook = new Workbook();
Worksheet sheet = workbook.Worksheets[0];
sheet.Name = "销售汇总报表";
// 标题行
CellRange title = sheet.Range["A1:E1"];
title.Merge();
title.Text = "销售汇总报表";
title.Style.Font.FontName = "宋体";
title.Style.Font.Size = 16;
title.Style.Font.Color = Color.White;
title.Style.Color = Color.DarkBlue;
title.Style.HorizontalAlignment = HorizontalAlignType.Center;
title.Style.VerticalAlignment = VerticalAlignType.Center;
sheet.Rows[0].RowHeight = 30;
// 表头
string[] headers = { "订单编号", "产品名称", "销售区域", "订单日期", "销售金额" };
for (int i = 0; i < headers.Length; i++)
{
CellRange cell = sheet.Range[2, i + 1];
cell.Text = headers[i];
cell.Style.Font.IsBold = true;
cell.Style.Color = Color.LightGray;
cell.Style.Borders[BordersLineType.EdgeBottom].LineStyle = LineStyleType.Medium;
cell.Style.Borders[BordersLineType.EdgeBottom].Color = Color.DarkBlue;
}
// 数据
object[][] data =
{
new object[] { 1001, "笔记本电脑", "北区", "2024-01-15", 15000 },
new object[] { 1002, "显示器", "西区", "2024-02-10", 12000 },
new object[] { 1003, "键盘", "东区", "2024-03-05", 13500 },
new object[] { 1004, "鼠标", "南区", "2024-04-12", 16000 }
};
for (int r = 0; r < data.Length; r++)
{
for (int c = 0; c < data[r].Length; c++)
{
CellRange cell = sheet.Range[r + 3, c + 1];
var value = data[r][c];
// 隔行填充不同背景色
cell.Style.Color = (r % 2 == 0)
? Color.LightYellow
: Color.LightCyan;
if (c == 3) // 订单日期
{
cell.DateTimeValue = DateTime.Parse(value.ToString());
cell.NumberFormat = "yyyy-MM-dd";
}
else if (c == 4) // 销售金额
{
cell.NumberValue = Convert.ToDouble(value);
cell.NumberFormat = "\"¥\"#,##0.00";
}
else
{
cell.Text = value.ToString();
}
}
}
// 添加边框
CellRange range = sheet.Range["A2:E6"];
range.BorderAround(LineStyleType.Medium, Color.Black);
range.BorderInside(LineStyleType.Thin, Color.Gray);
// 自动调整列宽
for (int i = 1; i <= 5; i++)
{
sheet.AutoFitColumn(i);
}
// 条件格式
XlsConditionalFormats formats = sheet.ConditionalFormats.Add();
formats.AddRange(sheet.Range["E3:E6"]);
IConditionalFormat condition = formats.AddCondition();
condition.FormatType = ConditionalFormatType.CellValue;
condition.Operator = ComparisonOperatorType.Greater;
condition.FirstFormula = "14000";
condition.FontColor = Color.Red;
condition.IsBold = true;
// 对齐和布局格式设置
CellRange all = sheet.AllocatedRange;
for (int r = 1; r < all.RowCount; r++)
{
all.Rows[r].HorizontalAlignment = HorizontalAlignType.Center;
all.Rows[r].VerticalAlignment = VerticalAlignType.Center;
all.Rows[r].RowHeight = 20;
}
for (int c = 0; c < all.ColumnCount; c++)
{
all.Columns[c].ColumnWidth = (c == 1) ? 19 : 14;
}
// 保存文件
workbook.SaveToFile("销售汇总报表.xlsx", ExcelVersion.Version2016);
workbook.Dispose();
}
}
输出:

格式化是创建专业 Excel 文档的重要步骤。借助 Spire.XLS for .NET,您可以高效地自定义单元格外观、控制数字和日期格式、管理工作表布局、应用条件格式,并完全通过 C# 构建视觉效果出色的报表。
通过使用本指南介绍的技术,您可以自动化 Excel 格式化任务,并生成适用于业务、报表和数据分析场景的高质量电子表格。
可以。Spire.XLS for .NET 独立于 Microsoft Excel 运行,可直接通过代码创建、编辑和格式化电子表格。
不会。大多数格式化操作仅影响数据的显示方式。除非显式修改,否则底层值保持不变。
可以。样式可应用于区域、行、列或整个工作表,从而轻松保持格式一致性。
支持。该库支持常见的条件格式功能,包括突出显示规则、数据条、颜色刻度和图标集。
Spire.XLS 支持 XLS、XLSX、XLSM、CSV 以及其他多种电子表格格式的读取和写入。
将 Excel 工作表和图表导出为 SVG 矢量图形,能够以任意分辨率在网页上清晰呈现数据,同时保持文字的可选与可搜索性。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成此转换,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
工作表转 SVG 的核心流程分为三个阶段:首先通过 FetchFileToVFS 将字体文件和目标 Excel 文件载入 WASM 虚拟文件系统;然后实例化 Workbook 加载文件,获取目标工作表后调用 ToSVGStream 将工作表渲染为 SVG 并写入 Stream 对象;最后从 VFS 读取生成的 SVG 文件,封装为 Blob 后触发浏览器下载。
function App() {
const sheetToSVG = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体和 Excel 文件载入 VFS
await window.spire.FetchFileToVFS('arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'ImageHeaderFooter.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿,获取第一个工作表
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
const sheet = workbook.Worksheets.get(0);
// 将工作表转换为 SVG 流
const outputFileName = "Worksheet.svg";
let fs = new xlsModule.Stream(outputFileName);
sheet.ToSVGStream(fs, 0, 0, 0, 0);
fs.Flush();
fs.Dispose();
// 从 VFS 读取转换后的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: "image/svg+xml;charset=utf-8"});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
// 释放资源
workbook.Dispose();
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Convert Excel To SVG</h1>
<button onClick={sheetToSVG}>
Generate
</button>
</div>
);
}
export default App;
工作表通过 ToSVGStream 转换后生成的 SVG 输出

图表工作表(ChartSheet)是一种特殊的工作表类型,其中包含嵌入式图表而非单元格数据。转换流程与工作表转 SVG 类似。
function App() {
const chartsheetToSVG = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体和 Excel 文件载入 VFS
await window.spire.FetchFileToVFS('arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'ChartSheet.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 按名称获取图表工作表
let cs = workbook.GetChartSheetByName("Chart1");
// 定义输出文件名
const outputFileName = 'ChartSheetToSVG-out.svg';
// 创建流,将图表工作表转换为 SVG
const fs = new xlsModule.Stream(outputFileName);
cs.ToSVGStream(fs, 0, 0, 0, 0);
fs.Flush();
// 从 VFS 读取转换后的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: "image/svg+xml;charset=utf-8" });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
// 释放资源
workbook.Dispose();
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Convert Chartsheet To SVG</h1>
<button onClick={chartsheetToSVG}>
Generate
</button>
</div>
);
}
export default App;
图表工作表通过 ToSVGStream 转换后生成的 SVG 输出

| 特性 | SVG | PNG |
|---|---|---|
| 缩放质量 | 任意倍数清晰 | 放大后模糊 |
| 文字 | 可选择、可搜索 | 已栅格化(纯图片) |
| 文件体积 | 小(几 KB) | 高分辨率时较大 |
| CSS 样式 | 可内联样式 | 不支持 |
| 后续编辑 | 可在 Illustrator、Inkscape 中编辑 | 需像素级编辑 |
| 浏览器嵌入 | <img> 或 <embed> |
<img> 标签 |
选择建议:在网页中嵌入报表或需要文字可选的场景优先使用 SVG;需要兼容图片编辑器或对接遗留系统的场景使用 PNG。
原因:WASM 虚拟文件系统中缺少渲染所需的字体文件。ToSVGStream 渲染文本时需从 VFS 中读取字体,若未预加载则文字区域会留白或显示为乱码。
解决:转换前通过 FetchFileToVFS 将字体文件载入 VFS:
await window.spire.FetchFileToVFS(
'ARIAL.TTF', '/Library/Fonts/', '/'
);
原因:创建 Blob 时 MIME 类型设置错误,浏览器无法正确识别文件格式。
解决:确保使用准确的 SVG MIME 类型:
const blob = new Blob([data], {
type: "image/svg+xml;charset=utf-8"
});
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。

在 Python 中将 HTML 转换为 Markdown,是开发者处理网页内容、技术文档或 API 数据时非常常见的需求。虽然 HTML 具备强大的结构化与格式化能力但在技术写作或静态网站生成等场景中,它可能显得冗长且难以维护。相比之下,Markdown 更轻量、可读性更高,并且兼容 GitHub、GitLab、Jekyll、Hugo 等现代内容平台。
利用 Python 自动化完成 HTML 到 Markdown 的转换,不仅可以简化工作流程,还能减少手动操作错误,并确保输出格式统一。本指南涵盖了从转换 HTML 文件和字符串到批量处理多个文件的所有内容,同时提供了确保 Markdown 转换结果准确的最佳实践。
在开始编码之前,我们先看看为什么很多开发者更倾向于在工作流中使用 Markdown,而不是直接使用 HTML。
总的来说,将 HTML 转换为 Markdown 可以提升内容可维护性、减少冗余,并更好地融入现代开发者工作流。
在 Python 中进行 HTML 转 Markdown 之前,你需要一个能够同时处理这两种格式的库。Spire.Doc for Python 是一个可靠的选择,它能够将 HTML 文件或 HTML 字符串转换为 Markdown,同时保持标题、列表、图片和链接的完整性。
你可以通过 pip 从 PyPI 安装:
pip install spire.doc
安装完成后,你就可以在 Python 脚本中自动化执行 HTML 转 Markdown 操作。该库同样支持更多文档转换场景。例如,当你需要可编辑文档时,可以依赖其 HTML 到 Word 的转换功能,将网页内容转换为 Word 文件。而当你需要归档或分发文档时,HTML 转 PDF 功能则可以生成统一、跨平台的 PDF 文档。
最常见的场景之一,就是将现有的 .html 文件转换为 .md 文件。这在将旧网站、技术文档或博客文章迁移到基于 Markdown 的工作流程(如静态网站生成器 Jekyll、Hugo,或基于 Git 的文档平台 GitHub、GitLab、Read the Docs)时特别有用。
from spire.doc import *
# 创建 Document 实例
doc = Document()
# 加载 HTML 文件
doc.LoadFromFile("input.html", FileFormat.Html)
# 保存为 Markdown 文件
doc.SaveToFile("output.md", FileFormat.Markdown)
# 关闭文档
doc.Close()
该代码会将 input.html 转换为 output.md,并保留标题、段落、列表、链接和图片等结构元素。

如果您对逆过程也感兴趣,可以查阅在 Python 中将 Markdown 转换为 HTML 的指南。
有时,HTML 内容并非存储在文件中,而是动态生成的——例如,从 API 获取网页内容或进行网页抓取时。在这些场景中,你可以直接从 HTML 字符串进行转换,而无需创建临时 HTML 文件。
from spire.doc import *
# HTML 字符串
html_content = """
<h1>HTML 字符串转换测试</h1>
<p>本测试用于验证将 <strong>HTML 字符串</strong> 直接转换为 <em>Markdown</em> 的效果。</p>
<ul>
<li>支持 <code>行内代码</code></li>
<li>支持<a href="https://example.com">超链接</a></li>
</ul>
"""
# 创建 Document 实例
doc = Document()
# 添加 Section
section = doc.AddSection()
# 添加段落并插入 HTML 字符串
paragraph = section.AddParagraph()
paragraph.AppendHTML(html_content)
# 保存为 Markdown
doc.SaveToFile("string_output.md", FileFormat.Markdown)
# 关闭文档
doc.Close()
生成的 Markdown 如下所示:

在大型项目中,你可能需要批量转换多个 .html 文件。一个简单的循环即可自动完成该过程。
import os
from spire.doc import *
# HTML 文件所在目录
input_folder = "html_files"
# Markdown 输出目录
output_folder = "markdown_files"
# 如果输出目录不存在则自动创建
os.makedirs(output_folder, exist_ok=True)
# 遍历输入目录中的所有文件
for filename in os.listdir(input_folder):
# 仅处理 .html 文件
if filename.endswith(".html"):
# 创建 Document 对象
doc = Document()
# 加载 HTML 文件
doc.LoadFromFile(
os.path.join(input_folder, filename),
FileFormat.Html
)
# 生成输出文件路径
output_file = os.path.join(
output_folder,
filename.replace(".html", ".md")
)
# 保存为 Markdown 文件
doc.SaveToFile(output_file, FileFormat.Markdown)
# 关闭文档释放资源
doc.Close()
此脚本会处理 html_files/ 文件夹中的所有 .html 文件,并将 Markdown 结果保存到 markdown_files/ 文件夹中。
将 HTML 转换为 Markdown 能提升内容可读性、维护性与版本控制效率。为了获得更准确、更干净的转换结果,建议遵循以下最佳实践。
在 Python 中将 HTML 转换为 Markdown 对于处理文档管道、迁移网页内容或处理来自 API 的数据的开发者来说,是一项宝贵的技能。借助 Spire.Doc for Python,你可以:
通过这些方法,你可以显著简化工作流程,并确保内容更加整洁、易维护,更适合现代发布平台。
答:可以。Spire.Doc 支持 Markdown 转 HTML,实现双向格式转换。
答:Spire.Doc 能较好地处理标准 HTML 元素,但对于复杂布局(如嵌套表格、多层结构),建议转换后手动检查结果,以确保转换结果的准确性。
答:当然可以。你可以使用 Python 脚本自动执行批量转换,从而一次性高效地处理多个 HTML 文件。
Spire.Doc for Python 14.6.1 现已正式发布。该版本完善了多项文档处理与图表操作能力,主要功能包括获取图表的 X 轴和 Y 轴数据值,将 Word 直接保存为 XLSX 格式, 以及在段落中追加 SmartArt 图形等。此外,还成功修复了一个在转换 Word 到 PDF 时出现的问题。详情请查阅以下内容。
新功能:
textRange.CharacterFormat.Kerning = kerningValue
doc = Document()
doc.LoadFromFile(inputFile)
sb = []
number = 1
for i in range(doc.Sections.Count):
sec = doc.Sections.get_Item(i)
for j in range(sec.Paragraphs.Count):
paragraph = sec.Paragraphs.get_Item(j)
for k in range(paragraph.ChildObjects.Count):
obj = paragraph.ChildObjects[k]
if isinstance(obj, ShapeObject):
shape = obj
chart = shape.Chart
sb.append("\r\n\r\n第" + str(number) + "页:\r\n" + "获取所有X轴数据:")
# X 轴
for x in range(chart.XValues.Count):
xVal = chart.XValues[x]
sb.append(str(xVal.StringValue) + " ")
# 第一个系列 Y 轴
series = chart.Series[0]
sb.append("\r\n获取Y轴数据:")
for i in range(series.YValues.Count):
yVal = series.YValues.get_Item(i)
sb.append(str(yVal.Value) + " ")
number += 1
# 写入文件
File.WriteAllText(outputFile, "".join(sb))
doc.Dispose()
chart.Series[0].DataLabels.Position = position
doc1 = Document()
doc1.LoadFromFile(inputFile_1)
doc2 = Document()
doc2.LoadFromFile(inputFile_2)
options = CompareOptions()
options = CompareOptions()
options.IgnoreCaseChanges = True
options.IgnoreComments = True
options.IgnoreFields = True
options.IgnoreFootnotes = True
options.IgnoreTables = True
options.IgnoreTextboxes = True
doc1.Compare(doc2, "user", DateTime(), options)
# 保存比较后的文档
doc1.SaveToFile(outputFile, FileFormat.Docx2013)
doc1.Close()
doc2.Close()
doc = Document()
doc.LoadFromFile(inputFile)
revisionInfoCollection = doc.GetRevisionInfos()
sb = []
for revisionIndex in range(revisionInfoCollection.Count):
revisionInfo = revisionInfoCollection.get_Item(revisionIndex)
if revisionInfo.RevisionType == RevisionType.FormatChange:
if isinstance(revisionInfo.OwnerObject, TextRange):
text_range = revisionInfo.OwnerObject
sb.append("文本范围:" + text_range.Text + "\r\n")
doc.RevisionsView = RevisionsView.Original
sb.append("原始样式: " + "是否加粗: " + str(text_range.CharacterFormat.Bold) + "; " + "文本颜色: " + text_range.CharacterFormat.TextColor.ToString() + ", 高亮颜色: " + text_range.CharacterFormat.HighlightColor.ToString() + ", 字体名称: " + str(text_range.CharacterFormat.FontName) + ", 下划线样式: " + str(text_range.CharacterFormat.UnderlineStyle) + "\r\n")
doc.RevisionsView = RevisionsView.Final
sb.append("最终样式: " + "是否加粗: " + str(text_range.CharacterFormat.Bold) + "; " + "文本颜色: " + text_range.CharacterFormat.TextColor.ToString() + ", 高亮颜色: " + text_range.CharacterFormat.HighlightColor.ToString() + ", 字体名称: " + str(text_range.CharacterFormat.FontName) + ", 下划线样式: " + str(text_range.CharacterFormat.UnderlineStyle) + "\r\n")
File.WriteAllText(outputFile, "\n".join(sb))
doc.Close()
# 加载Word文档
document = Document()
document.LoadFromFile(inputFile)
# 保存为XLSX格式
document.SaveToFile(outputFile, FileFormat.XLSX)
document.Close()
options = doc.CompatibilityOptions
# 添加节点
node_new = smartArt.Nodes.Add()
node_new.Text = "地图"
shapeProperties = node_new.ShapeProperties[0]
# 设置图形的填充颜色
shapeProperties.Fill.FillType = FillType.Picture
picFileStream = Stream("Image/0.jpg")
# 设置图片填充
shapeProperties.Fill.SetImage(picFileStream)
shape = paragraph.AppendSmartArt(SmartArtType.RepeatingBendingProcess, 432, 252)
paragraph.Format.AdjustRightIndent = True
hasSmartArt=shape.HasSmartArt
smartArt = shape.SmartArt
firstRow.Hidden = True
doc = Document()
toPdf = ToPdfParameterList()
toPdf.GeneratorName = genName
doc.LoadFromFile(inputFile)
doc.SaveToFile(outputFile, toPdf)
问题修复:
Spire.XLS 16.6.1 现已正式发布。该版本优化了从 Excel 图表到图片的转换功能。同时,一些在调用 CalculateAllValue 方法计算公式值以及加载 ODS 文件时出现的问题也得以成功修复。更多详情如下。
问题修复:
Spire.OCR 2.2.12 现已发布。该版本修复了 OCR 引擎识别图片时无法保留缩进与行间距的问题,进一步提升了识别结果的版式保留效果。 详情如下。
问题修复:
我们很高兴地宣布 Spire.PDF for Java 12.6.1 正式发布。此次更新新增了对 SHA-256/SHA-512 证书数字签名 PDF 的支持,并支持在 OFD 转 PDF 时设置备用字体。此外,本版本还修复了多个与 PDF 转换和文本提取相关的问题。 本次发布的更新内容如下
新功能:
public static void main(String[] args) throws IOException {
// Create pdf document
PdfDocument doc = new PdfDocument();
// Load file from disk
doc.loadFromFile("Sample.docx");
// Load the X509 certificate for signature
PdfPKCS7Formatter formatter = new PdfPKCS7Formatter(new PdfCertificate("gary.pfx", "e-iceblue"), false);
// Create an instance of PdfOrdinarySignatureMaker using the loaded document and certificate
PdfOrdinarySignatureMaker signatureMaker = new PdfOrdinarySignatureMaker(doc, formatter);
// Create an instance of PdfCustomSignatureAppearance as the appearance for the signature
IPdfSignatureAppearance signatureAppearance = new PdfCustomSignatureAppearance();
// Make the signature with a specified name and the custom appearance
signatureMaker.makeSignature("Signature", signatureAppearance);
// Iterate through all hash algorithm types
for (HashAlgorithmType hashAlg : HashAlgorithmType.values()) {
// Skip SM3 (case-insensitive)
if ("SM3".equalsIgnoreCase(hashAlg.name())) {
continue;
}
try {
// Set the current hash algorithm
formatter.getProperties().setHashAlgorithm(hashAlg);
String filePath = "AddImageSignature_" + hashAlg.name() + ".pdf";
doc.saveToFile(filePath, FileFormat.PDF);
System.out.println("Succeed:" + hashAlg.name());
} catch (Exception ex) {
System.out.println("Error HashAlgorithmType:" + hashAlg.name());
System.out.println("Error Info:" + ex.getMessage());
}
}
// Close the document
doc.close();
}
// Custom signature appearance implementation
public static class PdfCustomSignatureAppearance implements IPdfSignatureAppearance {
@Override
public void generate(PdfCanvas pdfCanvas) {
// Set font size
int fontSize = 10;
// Create Arial font
PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial", Font.PLAIN, fontSize), true);
// Set line height
float lineHeight = fontSize;
// Draw text string
pdfCanvas.drawString("AAAAAAAAAAA", font, PdfBrushes.getRed(), new Point.Float(0, 0));
// Draw image at specified position
pdfCanvas.drawImage(PdfImage.fromFile("E-iceblue logo.png"), new Point.Float(20, 0));
}
}
OfdConverter converter = new OfdConverter(ofdFile.getAbsolutePath());
converter.getOptions().setDefaultFontName(fontName);
converter.toPdf(PdfPath);
CustomProgressNotifier progressNotifier =new CustomProgressNotifier(output_txt);
ofdConverter ofdconverter=new Ofdconverter(inputPath);
ofdconverter.registerProgressNotifier(progressNotifier);
ofdConverter.toPdf(outputPath);
CustomProgressNotifier progressNotifier2=new CustomProgressNotifier(output_txt2);
PdfToWordConverter converter=new PdfTowordConverter(inputPath2);
converter.registerProgressNotifier(progressNotifier2);
converter.saveToDocx(outputPath2)
问题修复: