Spire.XLS for Java 15.9.1 现已正式发布。该版本增强了从 Excel 到 HTML 的转换功能,并对出现的多个问题进行了修复。更多详情如下:
问题修复:

在 ASP.NET 应用程序中生成 PDF 是一个常见需求——无论是生成发票、报告、表单,还是导出动态内容。与其依赖复杂的 PDF API 或第三方打印驱动程序,不如使用 Spire.PDF for .NET,这是一款专业且轻量级的库,能够让开发人员以编程方式创建和操作 PDF 文档。
在本教程中,我们将演示如何在 ASP.NET Core Web 应用程序中使用 Spire.PDF for .NET 生成 PDF 文档,包括从零创建 PDF 以及将 HTML 转换为 PDF 的示例。
文章目录:
Spire.PDF 是一款专为开发人员设计的 .NET PDF 库,能够快速、可靠地处理 PDF 功能。其主要优势包括:
第一步:创建新的 ASP.NET Core Web 应用
第二步:通过 NuGet 安装 Spire.PDF
或者使用 程序包管理器控制台 (Package Manager Console) 安装:
Install-Package Spire.PDF
第三步:添加 PDF 生成控制器
using Microsoft.AspNetCore.Mvc;
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;
namespace PdfDemoApp.Controllers
{
public class PdfController : Controller
{
public IActionResult CreatePdf()
{
// 创建一个新的 PDF 文档
PdfDocument doc = new PdfDocument();
PdfPageBase page = doc.Pages.Add(PdfPageSize.A4, new PdfMargins(40));
// 在页面上绘制文本
PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("宋体", 25f, FontStyle.Regular), true);
PdfSolidBrush brush = new PdfSolidBrush(Color.Black);
page.Canvas.DrawString("通过 ASP.NET Core 创建 PDF", font, brush, 10, 50);
// 保存到内存流
using (MemoryStream ms = new MemoryStream())
{
doc.SaveToStream(ms);
doc.Close();
ms.Position = 0;
// 返回 PDF 文件
return File(ms.ToArray(), "application/pdf", "Generated.pdf");
}
}
}
}
第四步(可选):在视图中添加按钮或链接
打开 Views/Home/Index.cshtml (或你的首页视图文件)。添加如下按钮或链接:
<div>
<a asp-controller="Pdf" asp-action="CreatePdf" class="btn btn-primary">
从零创建 PDF
</a>
</div>
这里使用了 ASP.NET Core 的标签帮助器 (Tag Helpers) 来生成正确的路由(/Pdf/CreatePdf)。
效果图:

除了文本之外,Spire.PDF还支持向 PDF 添加多种元素,例如图片、图形、表格、列表、超链接、注释以及水印。更多详细信息和高级用法,请参阅 Spire.PDF 编程指南。
Spire.PDF允许将 HTML 内容直接转换为 PDF 文件。此功能特别适用于生成发票、报告、收据,或将带有样式的网页以一致的格式导出为 PDF。
要将 HTML 渲染为 PDF,Spire.PDF 依赖外部渲染引擎。目前可以选择 Qt WebEngine 或 Google Chrome 。在本指南中,我们将使用 Qt WebEngine。
配置 Qt 插件:
解压缩安装包,找到 plugins 目录,例如: C:\plugins-windows-x64\plugins
在代码中注册插件路径:
HtmlConverter.PluginPath = @"C:\plugins-windows-x64\plugins";
插件准备好后,你就可以参考前面步骤,在控制器中添加以下代码片段,从 HTML 内容生成 PDF 输出。
using Microsoft.AspNetCore.Mvc;
using Spire.Additions.Qt;
using Spire.Pdf.Graphics;
using System.Drawing;
namespace PdfDemoApp.Controllers
{
public class HtmlToPdfController : Controller
{
[HttpGet]
public IActionResult HtmlToPdf()
{
// 示例 HTML 字符串
string html = @"
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
h1 { color: #2563eb; }
</style>
</head>
<body>
<h1>ASP.NET Core:从 HTML 创建 PDF</h1>
<p>此 PDF 使用基于 Qt 的转换器生成。</p>
</body>
</html>";
// Qt 插件文件夹路径
// ⚠️ 确保该文件夹在服务器或部署环境中存在
string pluginPath = @"C:\plugins-windows-x64\plugins";
HtmlConverter.PluginPath = pluginPath;
// 创建临时文件路径(在服务器端)
string tempFile = Path.GetTempFileName();
// 使用 Qt 将 HTML 字符串转换为 PDF
HtmlConverter.Convert(
html,
tempFile,
enableJavaScript: true,
timeout: 100000, // 超时时间,毫秒
pageSize: new SizeF(595, 842), // A4 页面大小(点)
margins: new PdfMargins(40), // 40pt 边距
LoadHtmlType.SourceCode // 从 HTML 字符串加载
);
// 将生成的 PDF 读取到内存
byte[] fileBytes = System.IO.File.ReadAllBytes(tempFile);
// 清理临时文件
System.IO.File.Delete(tempFile);
// 将 PDF 返回到浏览器进行下载
return File(fileBytes, "application/pdf", "HtmlToPdf.pdf");
}
}
}
效果图:

此示例将行内 HTML 转换为格式准确的 PDF。你也可以加载外部 HTML 文件或 URL —— 更多信息请参阅详细指南:在 C# 中将 HTML 转换为 PDF。
借助 Spire.PDF for .NET,你可以轻松在 ASP.NET Core 应用程序中生成 PDF 。无论是从零开始创建 PDF,还是在 C# 中进行 HTML 转 PDF 转换,Spire.PDF 都能提供可靠、对开发者友好的解决方案 —— 无需任何外部依赖。
如果你还需要通过 Word 文档生成 PDF,可以使用 Spire.Doc for .NET ,这是 Spire 系列的另一款产品。两者结合使用,可以覆盖 PDF 文档生成的完整场景 。
通过集成这些工具,开发者能够简化工作流程,减少对 Adobe 或其他第三方组件的依赖,并确保输出文档的一致性与专业质量。这将使你的 ASP.NET PDF 解决方案更具 可扩展性、可维护性 ,并适用于企业级应用。
不需要。Spire.PDF 是独立的库,可以完全脱离 Adobe Acrobat 使用。
不可以。Word 转 PDF 功能由 Spire.Doc for .NET 提供,而不是 Spire.PDF。如果项目需要,你可以将两者结合使用。
Spire.PDF 支持为 PDF 设置密码、权限和数字签名,以保障文档安全。
支持。它既能在 ASP.NET Core中使用,也兼容 ASP.NET Framework 。
如果您需要去除生成文档中的评估提示或解除功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
Spire.Doc 13.9.3 现已正式发布。该版本新增用于在保存 PDF 文档时添加数字签名和时间戳的公共类;同时增强了书签列属性、文本替换时对 OfficeMath 的处理选项,以及转换为 PDF 时的页面布局设置。此外,本次修复了若干与 Word 转 PDF、文档加载和页面计数相关的问题。更多详情如下。
新功能:
Document sDoc = new Document();
sDoc.LoadFromFile(inputFile);
ToPdfParameterList toPdfParameter = new ToPdfParameterList();
toPdfParameter.DigitalSignatureInfo = new PdfDigitalSignatureInfo(pfxInputFile, pfxPassword, "Test signing", "Spire Doc"); // 数字签名
toPdfParameter.DigitalSignatureInfo.HashAlgorithm = PdfDigitalSignatureHashAlgorithm.RipeMD160;
toPdfParameter.DigitalSignatureInfo.SignatureDate = nowDateTime;
toPdfParameter.DigitalSignatureInfo.TimestampConfiguration = new PdfDigitalSignatureTimestampConfiguration("https://freetsa.org/tsr", "bill", "Password"); // 时间戳
sDoc.SaveToFile(outputFile3, toPdfParameter);
int firstColumn = doc.Bookmarks["t_insert"].FirstColumn;
int lastColumn = doc.Bookmarks["t_insert"].LastColumn;
SearchOptions op = new SearchOptions();
op.IgnoreOfficeMath = false;
doc.Replace("ab","new", op);
Document doc = new Document("xx.docx");
ToPdfParameterList toPdf = new ToPdfParameterList(){ PageLayout = PdfPageLayout.TwoColumnLeft };
doc.SaveToFile("xx.pdf", toPdf);
问题修复:
CSV(逗号分隔值)作为轻量级数据交换格式,广泛应用于财务报表、用户数据、分析结果等场景。在.NET 开发中,高效处理和解析 CSV 文件是一项基础且重要的技能。本文将介绍如何借助Spire.XLS for .NET 通过 C# 读取 CSV 文件,包括直接读取和将 CSV 转换为 DataTable 两种方式。
Spire.XLS for .NET 不仅是专业的 Excel 处理工具,还对 CSV 文件提供了完善支持,无需依赖 Microsoft Office,处理效率高且跨平台兼容。
安装步骤:
或通过程序包管理器控制台执行命令:
PM> Install-Package Spire.XLS
以下 C# 代码示例演示如何加载 CSV 文件、访问其中数据,并以表格格式将内容输出到控制台。
using Spire.Xls;
namespace ReadCSV
{
class Program
{
static void Main(string[] args)
{
// 创建 Workbook 实例
Workbook workbook = new Workbook();
// 加载 CSV 文件
workbook.LoadFromFile("库存表.csv", ",");
// 获取第一个工作表
Worksheet sheet = workbook.Worksheets[0];
// 获取已使用的范围
CellRange range = sheet.AllocatedRange;
// 遍历行和列
for (int row = 1; row <= range.RowCount; row++)
{
for (int col = 1; col <= range.ColumnCount; col++)
{
// 获取单元格值
string cellValue = range[row, col].Value;
Console.Write(cellValue + "\t");
}
Console.WriteLine();
}
Console.ReadLine();
}
}
}
核心说明:
运行效果:CSV 数据将以清晰的制表符分隔格式输出到控制台。

若需要通过 VB.NET 读取 CSV 文件,可使用 C# 到 VB.NET转换器 直接转换代码。
DataTable 是.NET 中灵活的内存数据结构,便于筛选、排序、绑定 UI 等高级操作。以下代码演示如何将 CSV 直接转换为 DataTable:
using Spire.Xls;
using System.Data;
namespace ReadCSV
{
class Program
{
static void Main(string[] args)
{
// 创建 Workbook 实例
Workbook workbook = new Workbook();
// 加载 CSV 文件
workbook.LoadFromFile("库存表.csv", ",");
// 获取第一个工作表
Worksheet worksheet = workbook.Worksheets[0];
// 将工作表中的数据导出到 DataTable
DataTable dataTable = worksheet.ExportDataTable();
// 获取行和列的数量
Console.WriteLine("\n转换完成!DataTable信息:");
Console.WriteLine($"列数:{dataTable.Columns.Count}");
Console.WriteLine($"行数:{dataTable.Rows.Count}");
Console.WriteLine();
// 打印列名
for (int i = 0; i < dataTable.Columns.Count; i++)
{
Console.Write(dataTable.Columns[i].ColumnName + " | ");
}
Console.WriteLine();
Console.WriteLine("----------------------------------------------------------");
// 打印行数据
for (int i = 0; i < dataTable.Rows.Count; i++)
{
for (int j = 0; j < dataTable.Columns.Count; j++)
{
string value = dataTable.Rows[i][j].ToString();
Console.Write(value + "\t");
}
Console.WriteLine();
}
}
}
}
核心说明:
Columns 和 Rows 属性快速获取元数据与内容。运行效果:输出包含列名、数据行及统计信息的结构化结果。

若需分析、计算或格式化数据,您可以通过 C# 将 CSV 转换为 Excel。
根据实际需求选择合适的方法:
| 方法 | 适用场景 | 典型用例 |
|---|---|---|
| 直接读取 CSV | 快速验证数据、简单打印输出 | 检查 CSV 文件是否正确加载、预览数据 |
| 转换为 DataTable | 复杂数据处理、绑定 UI 或数据库 | 筛选行、排序数据或保存到SQL Server |
借助 Spire.XLS for .NET,C# 处理 CSV 文件变得简单高效:直接读取适用于快速验证,转换为 DataTable 则便于高级操作。两种方法均无需依赖 Office,且代码可直接复用(只需修改文件路径)。
如需进一步了解格式转换、样式应用等高级功能,可参考 Spire.XLS 官方文档。
答:虽然 .NET Framework 提供了内置的 StreamReader 处理 CSV 文件,但 Spire.XLS 的优势在于:
答:只需将 LoadFromFile() 的第二个参数替换为实际分隔符即可:
// 读取制表符分隔的文件
workbook.LoadFromFile("data.txt", "\t");
// 读取分号分隔的文件
workbook.LoadFromFile("data.csv", ";");
// 读取竖线分隔的文件
workbook.LoadFromFile("data.csv", "|");
答:可以。通过定义范围实现精准读取,例如跳过标题行只取特定列:
// 定义特定范围
int startRow = 2; // 从第2行开始(跳过标题)
int endRow = 4; // 在第4行结束
int startCol = 2; // 从第2列开始
int endCol = 6; // 在第6列结束
// 遍历行和列
for (int row = startRow; row <= endRow; row++)
{
for (int col = startCol; col <= endCol; col++)
{
// 获取单元格值
string cellValue = worksheet.Range[row, col].Value;
Console.Write(cellValue + "\t");
}
Console.WriteLine();
}
注意:Spire.XLS 采用 1-based 索引(与Excel一致),因此第一行/列编号为1(而非0)。
我们很高兴地宣布 Spire.PDFViewer 8.1.8 的发布。此更新引入了对 Windows 上 MAUI 的支持,并解决了 PDF 内容无法完整显示的问题。更多详细信息如下。
新功能:
问题修复:
Spire.PDF for Python 11.9.0 现已正式发布。该版本支持在 PDF 中绘制表格,以及给多行文本添加批注。此外,它还修复了一个在转换后的HTML文件中出现的问题。详情请查阅以下内容。
新功能:
pdf = PdfDocument()
page = pdf.Pages.Add(PdfPageSize.A3())
pen = PdfPen(PdfRGBColor(Color.get_Black()), 0.1)
# 设置线框边界位置和大小
x = 5.0
y = 5.0
width = page.Size.Width - (x * 2)
height = page.Size.Height - (y * 2)
page.Canvas.DrawRectangle(pen, x, y, width, height)
# 添加表格
grid = PdfGrid()
row = grid.Rows.Add()
grid.Columns.Add(2)
for i in range(grid.Columns.Count):
grid.Columns[i].Width = 50
row.Cells[i].Value = "add{0:d}".format(i + 1)
border = PdfBorders()
border.All = PdfPen(Color.get_Gray())
for j in range(grid.Rows.Count):
cells = grid.Rows.get_Item(j).Cells
for k in range(cells.Count):
cells.get_Item(k).Style.Borders = border
# 绘制表格
grid.Draw(page, PointF(50.0, 50.0))
pdf.SaveToFile(outputFile)
pdf.Close()
pdf = PdfDocument()
pdf.LoadFromFile(inputFile)
page = pdf.Pages[0];
finder = PdfTextFinder(page)
finder.Options.Parameter = TextFindParameter.WholeWord
finder.Options.Parameter = TextFindParameter.IgnoreCase
fragments = finder.Find("亚里士多德提出的科学知识概念至今仍具影响力,他认为科学知识是一套可靠的知识体系,能够通过逻辑和理性进行阐释")
textFragment = fragments[0]
text = "此处为 Spire.PDF for .NET 添加的标记注释。"
quadPoints = [None for _ in range(len(textFragment.Bounds) * 4)]
for i in range(len(textFragment.Bounds)):
rect = textFragment.Bounds[i]
quadPoints[4 * i] = PointF(rect.Left, rect.Top)
quadPoints[4 * i + 1] = PointF(rect.Right, rect.Top)
quadPoints[4 * i + 2] = PointF(rect.Left, rect.Bottom)
quadPoints[4 * i + 3] = PointF(rect.Right, rect.Bottom)
annotation = PdfTextMarkupAnnotation(textFragment.Bounds[0], quadPoints)
annotation.Text = text
annotation.TextMarkupColor = PdfRGBColor(Color.get_Blue())
page.Annotations.Add(annotation)
pdf.SaveToFile(outputFile)
pdf.SaveAsImage(pageIndex,dpiX,dpiY)
问题修复:

Markdown (.md) 是一种在网页开发、文档撰写和技术写作中广受欢迎的格式。其简洁直观的语法不仅能够提升写作效率,还能让内容阅读更加顺畅。然而,浏览器无法直接解析 Markdown,因此将 Markdown 转换为 HTML 是保证内容结构清晰、排版规范,并能够在各类网页平台上正常显示的关键步骤。
本教程将展示如何使用 Python 和 Spire.Doc for Python 高效实现 Markdown 到 HTML 的转换。内容涵盖详细步骤与实用代码示例,既支持单文件转换,也可进行批量处理,帮助您快速掌握完整流程,实现高效、可靠的文档转换。
Markdown 是一种轻量级标记语言,旨在提升可读性和易写性。与繁琐的 HTML 相比,Markdown 使用简单的语法来表示标题、列表、链接和图片等元素。
示例 Markdown:
# 这是一个标题
这是一个包含 **粗体文本** 和 *斜体文本* 的段落。
- 项目 1
- 项目 2
即使在原始格式下,Markdown 也非常易于阅读,这使得它在文档、博客、README 文件和技术写作中备受青睐。
有关 Markdown 语法的更多信息,请参考 Markdown 指南。
虽然 Markdown 非常适合撰写内容,但网页浏览器并不能直接解析它。将 Markdown 转换为 HTML 可以为您带来以下好处:
通过将 Markdown 转换为 HTML,您可以充分利用这些优势,提升内容的展示效果和用户体验。
Spire.Doc for Python 是一个多功能的文档处理库,能够读取 Word 文档和 Markdown 文件,并将内容导出为 HTML。这个库让开发者可以用极少的代码轻松地将 Markdown 转换为 HTML,同时保持良好的格式和结构。
此外,Spire.Doc for Python 还支持将 Markdown 转换为 Word 或 PDF,这使其成为一个完整的解决方案,适合希望使用同一工具处理 Markdown 并输出为多种格式的开发者。
使用 Spire.Doc for Python 进行 Markdown 到 HTML 转换的优势
现在您已经了解了将 Markdown 转换为 HTML 的目的和好处,接下来,我们将逐步演示如何在 Python 中将 Markdown 文件转换为适合网页使用的 HTML。
首先,确保在您的环境中安装了 Spire.Doc for Python。您可以通过运行以下 pip 命令从 PyPI 安装它:
pip install spire.doc
接下来,创建一个示例 Markdown 文件,例如 example-zh.md,作为转换的对象。

编写一个 Python 脚本,加载 Markdown 文件并将其转换为 HTML:
from spire.doc import *
# 创建 Document 对象
doc = Document()
# 从文件加载 Markdown
doc.LoadFromFile("example-zh.md", FileFormat.Markdown)
# 将文档保存为 HTML
doc.SaveToFile("example-zh.html", FileFormat.Html)
# 关闭文档
doc.Close()
代码说明:
最后,在网页浏览器或 HTML 编辑器中打开生成的 example-zh.html 文件,确认 Markdown 内容是否已正确转换。

您可以自动化地转换文件夹中的多个 Markdown 文件。以下是示例代码:
import os
from spire.doc import *
# 设置包含 Markdown 文件的文件夹
input_folder = "markdown_files"
# 设置 HTML 文件保存的文件夹
output_folder = "html_files"
# 如果输出文件夹不存在,则创建
os.makedirs(output_folder, exist_ok=True)
# 遍历输入文件夹中的所有文件
for filename in os.listdir(input_folder):
# 仅处理 Markdown 文件
if filename.endswith(".md"):
# 为每个文件创建一个新的 Document 对象
doc = Document()
# 将 Markdown 文件加载到 Document 对象中
doc.LoadFromFile(os.path.join(input_folder, filename), FileFormat.Markdown)
# 设置输出文件路径
output_file = os.path.join(output_folder, filename.replace(".md", ".html"))
# 将 Markdown 内容保存为 HTML
doc.SaveToFile(output_file, FileFormat.Html)
# 关闭文档以释放资源
doc.Close()
这种方法能够高效处理多个 Markdown 文件,并自动生成相应的 HTML 文件。通过批量转换,您可以节省时间并提升工作效率。
虽然以上步骤已经可以完成 Markdown 到 HTML 的转换,但遵循一些实用建议可以帮助您避免常见问题,提升转换质量和输出效果:
通过使用 Python 和 Spire.Doc,您可以轻松将 Markdown 文件转换为 HTML。这种方法不仅高效便捷,还能完整保留文档的格式和结构,确保生成的 HTML 输出既美观又实用。无论您是处理单个文件还是进行批量转换,按照本指南的步骤,您都能高效地完成任务,提升工作效率。
A1: 可以。您可以通过遍历目录中的 Markdown 文件,并对每个文件应用转换逻辑,实现批量转换。
A2: 会。Spire.Doc 能够有效保留 Markdown 格式,包括标题、列表、粗体、斜体文本、链接等。
A3: Spire.Doc 支持转换嵌入在 Markdown 中的图片,确保它们保留在生成的 HTML 中。
A4: 不需要额外的库。Spire.Doc for Python 提供了一个全面的解决方案,可以在没有外部依赖的情况下将 Markdown 转换为 HTML。
A5: 可以,生成的 HTML 与流行的 Web 框架(如 React、Vue 和 Angular)完全兼容。

在企业级应用开发中,生成 PDF 文档是一项非常常见的需求。无论是发票、报告、合同,还是其他业务文档,开发人员通常都需要一种高效、稳定的方式来创建 PDF。与其逐行绘制 PDF 内容,不如直接利用 模板 ——常见的模板形式包括 HTML 模板 和 PDF 模板 ,开发者只需将动态数据填充进去,就能快速生成所需文档。
在本文中,我们将介绍如何使用 Spire.PDF for Java 通过模板生成 PDF 文件。文章不仅涵盖 HTML 模板和 PDF 模板的使用方法,还会提供一些高效生成文档的最佳实践和常见问题解答,帮助你在实际项目中更好地应用。
目录 :
Spire.PDF for Java是一个功能强大的 PDF 库,提供用于创建、读取、编辑和转换 PDF 文件的完整 API。它支持以下功能:
安装:
<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.pdf</artifactId>
<version>12.9.0</version>
</dependency>
</dependencies>
HTML 模板非常灵活,允许你通过 CSS 样式 自定义文档布局和外观。在模板中,你可以定义 占位符 (使用 {{ }} 包裹),在运行时动态替换成实际数据,从而生成个性化的 PDF 文档。
安装 HTML 转 PDF 渲染引擎
Spire.PDF 依赖外部引擎来将 HTML 渲染为 PDF,可以选择 Qt WebEngine或 Google Chrome 。在本指南中,我们将使用 Qt WebEngine 。
下载适用于操作系统的 Qt WebEngine 插件:
将下载的文件解压到本地文件夹,并找到 plugins 目录,例如:C:\plugins-windows-x64\plugins
在代码中配置插件路径:
HtmlConverter.setPluginPath("C:\\plugins-windows-x64\\plugins");
完成插件配置后,Spire.PDF 就可以将 HTML 完整渲染为 PDF,并支持 CSS 样式,实现高保真的文档转换。
示例:从 HTML 模板生成发票 PDF
import com.spire.pdf.graphics.PdfMargins;
import com.spire.pdf.htmlconverter.LoadHtmlType;
import com.spire.pdf.htmlconverter.qt.HtmlConverter;
import com.spire.pdf.htmlconverter.qt.Size;
import java.util.HashMap;
import java.util.Map;
public class CreatePdfFromHtmlTemplate {
public static void main(String[] args) {
// HTML 模板,使用双大括号 {{}} 作为占位符变量
String htmlTemplate = "<!DOCTYPE html>\n" +
"<html lang=\"zh\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
" <title>发票</title>\n" +
" <style>\n" +
" body {\n" +
" font-family: 宋体, sans-serif;\n" +
" margin: 20px;\n" +
" padding: 20px;\n" +
" font-size: 12pt;\n" +
" }\n" +
" h1 {\n" +
" text-align: left;\n" +
" font-size: 30pt;\n" +
" }\n" +
" h2 {\n" +
" font-size: 18pt;\n" +
" }\n" +
" .invoice-header, .invoice-footer {\n" +
" text-align: left;\n" +
" margin-bottom: 20px;\n" +
" }\n" +
" .invoice-details {\n" +
" margin-bottom: 20px;\n" +
" }\n" +
" table {\n" +
" width: 100%;\n" +
" border-collapse: collapse;\n" +
" }\n" +
" th, td {\n" +
" border: 1px solid #ccc;\n" +
" padding: 8px;\n" +
" text-align: left;\n" +
" }\n" +
" th {\n" +
" background-color: #f2f2f2;\n" +
" }\n" +
" .total {\n" +
" font-weight: bold;\n" +
" }\n" +
" </style>\n" +
"</head>\n" +
"<body>\n" +
" <div class=\"invoice-header\">\n" +
" <h1>发票</h1>\n" +
" <p>发票编号: {{INVOICE_NUMBER}}</p>\n" +
" <p>日期: {{INVOICE_DATE}}</p>\n" +
" </div>\n" +
" <div class=\"invoice-details\">\n" +
" <h2 style=\"margin-top: 50px;\">开票给:</h2>\n" +
" <p>姓名: {{BILLER_NAME}}</p>\n" +
" <p>地址: {{BILLER_ADDRESS}}</p>\n" +
" <p>邮箱: {{BILLER_EMAIL}}</p>\n" +
" </div>\n" +
" <table>\n" +
" <thead>\n" +
" <tr>\n" +
" <th>描述</th>\n" +
" <th>数量</th>\n" +
" <th>单价</th>\n" +
" <th>总计</th>\n" +
" </tr>\n" +
" </thead>\n" +
" <tbody>\n" +
" <tr>\n" +
" <td>{{ITEM_DESCRIPTION}}</td>\n" +
" <td>{{ITEM_QUANTITY}}</td>\n" +
" <td>{{ITEM_UNIT_PRICE}}</td>\n" +
" <td>{{ITEM_TOTAL}}</td>\n" +
" </tr>\n" +
" <!-- 如有需要,可添加更多项目 -->\n" +
" </tbody>\n" +
" </table>\n" +
" <div class=\"total\" style=\"text-align: right;\">\n" +
" <p>小计: {{SUBTOTAL}}</p>\n" +
" <p>税率 ({{TAX_RATE}}%): {{TAX}}</p>\n" +
" <p>总计: {{TOTAL}}</p>\n" +
" </div>\n" +
" <div class=\"invoice-footer\">\n" +
" <p>感谢您的惠顾!</p>\n" +
" </div>\n" +
"</body>\n" +
"</html>";
// 发票示例数据 - 与模板占位符对应的键值对
Map<String, String> invoiceData = new HashMap<>();
invoiceData.put("INVOICE_NUMBER", "12345");
invoiceData.put("INVOICE_DATE", "2025-08-25");
invoiceData.put("BILLER_NAME", "张三");
invoiceData.put("BILLER_ADDRESS", "北京市朝阳区123号");
invoiceData.put("BILLER_EMAIL", "zhangsan@ example.com");
invoiceData.put("ITEM_DESCRIPTION", "咨询服务");
invoiceData.put("ITEM_QUANTITY", "10");
invoiceData.put("ITEM_UNIT_PRICE", "¥100");
invoiceData.put("ITEM_TOTAL", "¥1000");
invoiceData.put("SUBTOTAL", "¥1000");
invoiceData.put("TAX_RATE", "5");
invoiceData.put("TAX", "¥50");
invoiceData.put("TOTAL", "¥1050");
// 用实际数据填充 HTML 模板
String populatedInvoice = populateInvoice(htmlTemplate, invoiceData);
// 指定生成 PDF 的输出路径
String outputFile = "output/HtmlToPdf.pdf";
// 指定 HTML 转 PDF 转换器插件路径(QT 插件)
String pluginPath = "C:\\plugins-windows-x64\\plugins";
// 设置 HTML 转 PDF 所需的插件路径
HtmlConverter.setPluginPath(pluginPath);
// 将 HTML 字符串转换为 PDF 并指定相关设置
HtmlConverter.convert(populatedInvoice, outputFile,
true, // 启用 JavaScript
100000, // 超时时间(毫秒)
new Size(595, 842), // A4 页面大小(595x842磅)
new PdfMargins(20), // 四边 20 点边距
LoadHtmlType.Source_Code); // 从 HTML 源代码字符串加载
}
// 辅助方法:用数据 Map 中的实际值替换模板占位符
private static String populateInvoice(String template, Map<String, String> data) {
String result = template;
for (Map.Entry<String, String> entry : data.entrySet()) {
result = result.replace("{{" + entry.getKey() + "}}", entry.getValue());
}
return result;
}
}
工作原理
这种方法非常适合 发票、收据和报表 等对格式有要求的文档生成场景。
效果图:

您可以能感兴趣:Java 将 URL、HTML 字符串或文件转换为 PDF
如果你已经有一个预先设计好的 PDF 表单或模板,可以直接在 PDF 内部 替换占位符 来生成新的文档。
示例:替换 PDF 模板中的文本
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.texts.PdfTextReplaceOptions;
import com.spire.pdf.texts.PdfTextReplacer;
import com.spire.pdf.texts.ReplaceActionType;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
public class CreatePdfFromPdfTemplate {
public static void main(String[] args) {
// 创建 PdfDocument 对象
PdfDocument doc = new PdfDocument();
// 加载现有 PDF 文件
doc.loadFromFile("C:\\Users\\Administrator\\Desktop\\Template.pdf");
// 创建 PdfTextReplaceOptions 对象并指定替换选项
PdfTextReplaceOptions textReplaceOptions = new PdfTextReplaceOptions();
textReplaceOptions.setReplaceType(EnumSet.of(ReplaceActionType.WholeWord));
// 获取指定页面(此处为第一页)
PdfPageBase page = doc.getPages().get(0);
// 基于页面创建 PdfTextReplacer 对象
PdfTextReplacer textReplacer = new PdfTextReplacer(page);
textReplacer.setOptions(textReplaceOptions);
// 定义旧字符串和新字符串的字典
Map<String, String> replacements = new HashMap<>();
replacements.put("{PROJECT_NAME}", "新网站开发");
replacements.put("{PROJECT_NO}", "2023-001");
replacements.put("{PROJECT MANAGER}", "王五");
replacements.put("{PERIOD}", "2023年第3季度");
replacements.put("{START_DATE}", "2023年7月1日");
replacements.put("{END_DATE}", "2023年9月30日");
// 遍历字典,替换占位符文本
for (Map.Entry<String, String> pair : replacements.entrySet()) {
textReplacer.replaceText(pair.getKey(), pair.getValue());
}
// 保存修改后的 PDF 到新的文件
doc.saveToFile("output/ModifyTemplate.pdf");
doc.dispose();
}
}
工作原理
注意事项
多行文本的替代方案
效果图:

可以,但需要使用 Spire.Doc for Java。它允许你替换 Word 文档中的占位符,然后将结果导出为 PDF。
可以。使用 Spire.PDF,无论是基于 HTML 模板生成,还是修改现有 PDF 模板,都可以嵌入图片、图表和形状。
是的,需要插件来准确渲染带样式和 CSS 的 HTML。
建议:简单文档使用 Qt WebEngine,要求与最新浏览器渲染效果一致时使用 Google Chrome。
支持。Spire.PDF 完全支持 Unicode,可以生成包含多种语言(如英文、中文、阿拉伯语或印地语)的 PDF,且不会丢失格式。
通过将 Spire.PDF集成到 Java 项目中,你可以从 HTML 模板 或 PDF 模板 高效生成专业的 PDF 文档。根据不同场景的需求:
如果你的工作流程已经依赖 Word 模板,可以考虑使用 Spire.Doc for Java ,它能够:
这种灵活性让你可以根据模板格式选择合适的工具 —— Spire.PDF 或 Spire.Doc ,从而确保 PDF 输出既高效又高质量。
如果您需要去除生成文档中的评估提示或解除功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
Spire.Office 10.8.0 更新已发布。在该版本中,Spire.Doc 支持比较两个列表级别是否一致;Spire.Presentation 加强了PPTX 转 PDF;Spire.PDF 支持转换 PDF 到 SVG 时设置 SVG 文件的宽高。此外,大量已知问题在该版本中成功修复。详情请阅读以下内容。
该版本涵盖了最新版的 Spire.Doc、Spire.PDF、Spire.XLS、Spire.Presentation、Spire.Barcode、Spire.Email、Spire.DocViewer、Spire.PDFViewer、Spire.OfficeViewer 和 Spire.DataExport。
https://www.e-iceblue.cn/Downloads/Spire-Office-NET.html
新功能:
// 创建 Document 对象
Document document = new Document();
// 创建列表样式
ListStyle listStyle_1 = document.Styles.Add(ListType.Bulleted, "bulletList");
ListLevelCollection Levels_1 = listStyle_1.ListRef.Levels;
ListLevel L0 = Levels_1[0];
ListLevel L1 = Levels_1[1];
ListLevel L2 = Levels_1[2];
ListStyle listStyle_2 = document.Styles.Add(ListType.Bulleted, "bulletList");
ListLevelCollection Levels_2 = listStyle_2.ListRef.Levels;
ListLevel l0 = Levels_2[0];
ListLevel l1 = Levels_2[1];
ListLevel l2 = Levels_2[2];
// 设置列表样式
L0.ParagraphFormat.LineSpacing = 10 * 1.5f;
L1.CharacterFormat.FontSize = 9;
L1.IsLegalStyleNumbering = true;
L1.PatternType = ListPatternType.Arabic;
L1.FollowCharacter = FollowCharacterType.Nothing;
L1.BulletCharacter = "\x006e";
L1.NumberAlignment = ListNumberAlignment.Left;
L1.NumberPosition = -10;
L1.TabSpaceAfter = 0.5f;
L1.TextPosition = 0.5f;
L1.StartAt = 4;
L1.NumberSufix = "章";
L1.NumberPrefix = "第";
L1.NoRestartByHigher = false;
L1.UsePrevLevelPattern = false;
L2.CharacterFormat.FontName = "黑体";
// 创建列表样式2
l0.ParagraphFormat.LineSpacing = 10 * 1.5f;
l1.CharacterFormat.FontSize = 9;
l1.IsLegalStyleNumbering = true;
l1.PatternType = ListPatternType.Arabic;
l1.FollowCharacter = FollowCharacterType.Nothing;
l1.BulletCharacter = "\x006e";
l1.NumberAlignment = ListNumberAlignment.Left;
l1.NumberPosition = -10;
l1.TabSpaceAfter = 0.5f;
l1.TextPosition = 0.5f;
l1.StartAt = 4;
l1.NumberSufix = "章节";
l1.NumberPrefix = "第";
l1.NoRestartByHigher = false;
l1.UsePrevLevelPattern = false;
l1.CreatePictureBullet();
l2.CharacterFormat.FontName = "黑体";
// 比较两个列表级别是否一致
bool r0 = L0.Equals(l0);
bool r1 = L1.Equals(l1);
bool r2 = L2.Equals(l2);
// 创建 Document 对象
Document document = new Document();
// 添加一节
Section sec = document.AddSection();
Spire.Doc.Documents.Paragraph paragraph = sec.AddParagraph();
// 创建列表样式
ListStyle listStyle = document.Styles.Add(ListType.Bulleted, "bulletList");
ListLevelCollection Levels = listStyle.ListRef.Levels;
Levels[0].CreatePictureBullet();
Levels[0].PictureBullet.LoadImage(@"logo.jpg");
Levels[1].CreatePictureBullet();
Levels[1].PictureBullet.LoadImage(@"py.jpg");
// 添加段落并应用段落样式
paragraph = sec.AddParagraph();
paragraph.AppendText("项目 1");
paragraph.ListFormat.ApplyStyle(listStyle);
paragraph = sec.AddParagraph();
paragraph.AppendText("项目 1.1");
paragraph.ListFormat.ApplyStyle(listStyle);
paragraph.ListFormat.ListLevelNumber = 1;
// 删除图片项目符号
Levels[0].DeletePictureBullet();
// 保存文件
document.SaveToFile(@"out.docx", FileFormat.Docx);
document.Close();
调整:
// 创建 Document 对象
Document document = new Document();
// 添加一节
Section sec = document.AddSection();
Spire.Doc.Documents.Paragraph paragraph = sec.AddParagraph();
// 创建列表模板1
ListTemplate template = ListTemplate.BulletDefault;
ListDefinitionReference listRef = document.ListReferences.Add(template);
// 创建列表模板2
ListTemplate template1 = ListTemplate.NumberDefault;
ListDefinitionReference listRef1 = document.ListReferences.Add(template1);
listRef1.Levels[2].StartAt = 4;
int levelcount = listRef.Levels.Count;
// 添加段落并应用样式
paragraph = sec.AddParagraph();
paragraph.AppendText("项目 1");
paragraph.ListFormat.ApplyListRef(listRef, 1);
paragraph = sec.AddParagraph();
paragraph.AppendText("项目 2");
paragraph.ListFormat.ApplyListRef(listRef, 2);
paragraph = sec.AddParagraph();
paragraph.AppendText("项目3");
paragraph.ListFormat.ApplyListRef(listRef1, 1);
paragraph = sec.AddParagraph();
paragraph.AppendText("项目 4");
paragraph.ListFormat.ApplyListRef(listRef1, 2);
// 保存文件
document.SaveToFile("out.docx", FileFormat.Docx);
document.Close();
ListStyle listStyle = document.Styles.Add(ListType.Numbered, "levelstyle");
listStyle.IsCustomStyle = true;
listStyle.CharacterFormat.FontName = "Trebuchet MS";
ListLevelCollection levels = listStyle.ListRef.Levels;
levels[0].PatternType = ListPatternType.Arabic;
levels[0].StartAt = 1;
levels[0].CharacterFormat.FontName = "Trebuchet MS";
ListStyle numberList2 = document.Styles.Add(ListType.Numbered, "Numbered2");
ListLevelCollection Levels = numberList2.ListRef.Levels;
Levels[0].StartAt = 10;
更新依赖项:
Microsoft.Win32.Registry >= 4.5.0
System.Drawing.Common >= 4.7.2
System.Security.Permissions >= 4.7.0
System.Text.Encoding.CodePages >= 4.5.0
System.Security.Cryptography.Pkcs >= 4.7.0
System.Security.Cryptography.Xml >=4.7.1
HarfBuzzSharp >=8.3.0.1
Microsoft.Win32.Registry >= 5.0.0
System.Drawing.Common >= 6.0.0
System.Security.Permissions >= 6.0.0
System.Text.Encoding.CodePages >= 6.0.0
System.Security.Cryptography.Pkcs >= 6.0.5
System.Security.Cryptography.Xml >= 6.0.2
HarfBuzzSharp >=8.3.0.1
问题修复:
新功能:
PdfToSvgConverter converter = new PdfToSvgConverter(inputFile);
converter.SvgOptions.ScaleX = (float)0.5;
converter.SvgOptions.ScaleY = (float)0.5;
converter.Convert(outputFile);
优化:
调整:
问题修复:
手动向 Excel 工作表中输入数据既耗时又容易出错,尤其是在处理大型数据集时。而借助合适的 Java Excel 库,可以简化数据输入这一流程。本文将详细介绍如何使用 Spire.XLS for Java 库,通过 3 种高效方法完成 Java 向 Excel 工作表的数据写入,涵盖基础的逐个单元格录入、批量数组插入以及 DataTable 导出。
开始之前,需先将 Spire.XLS for Java 集成到项目中,以下为两种快速部署方式:
方式 1:手动下载 JAR 包
方式 2:Maven 依赖集成
在项目 pom.xml 中添加以下仓库和依赖,Maven 会自动下载并引入库(无需手动处理依赖冲突):
<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>
Spire.XLS for Java 提供了灵活的数据写入方法,可适配不同使用场景。以下将结合完整代码示例、说明及适用场景,逐一介绍每种方法。
若需向单个单元格填充文本或数字,Spire.XLS 支持通过行、列索引(例如(2,1)代表第 2 行第 1 列)或 Excel 样式引用(例如"A1"、"B3")直接定位目标单元格:
核心方法:
Worksheet.get(int row, int column) 或 Worksheet.get(String name) 方法获取指定 Excel 单元格setValue() 方法向单元格写入文本值setNumberValue() 方法向单元格写入数值Java 代码示例:
import com.spire.xls.*;
public class WriteToCells {
public static void main(String[] args) {
// 创建 Workbook 对象
Workbook workbook = new Workbook();
// 获取第一个工作表
Worksheet worksheet = workbook.getWorksheets().get(0);
// 向指定单元格写入数据
worksheet.get("A1").setValue("物品名");
worksheet.get("B1").setValue("数量");
worksheet.get("C1").setValue("分类");
worksheet.get("D1").setValue("采购日期");
worksheet.get(2,1).setValue("键盘");
worksheet.get(2,2).setNumberValue(12);
worksheet.get(2,3).setValue("办公用品");
worksheet.get(2,4).setValue("2024/11/09");
worksheet.get(3,1).setValue("毛巾");
worksheet.get(3,2).setNumberValue(30);
worksheet.get(3,3).setValue("生活用品");
worksheet.get(3,4).setValue("2024/12/18");
// 为第一行应用样式
CellStyle style = workbook.getStyles().addStyle("newStyle");
style.getFont().isBold(true); // 设置字体为粗体
worksheet.getRange().get(1,1,1,4).setStyle(style);
// 保存为 Excel 文件
workbook.saveToFile("写入数据到单元格.xlsx", ExcelVersion.Version2016);
}
}
适用场景:
适用于小型数据集,且需要精确控制单元格位置的场景(例如添加标题、单行数据录入)。
效果预览:

将一维数组(单行)或二维数组(多行多列)一次性插入连续单元格区域,能提升逐个写入的效率。
核心 API:insertArray() 解析
insertArray() 方法可轻松处理一维数组(单行数据)和二维数组(多行多列数据),其参数说明如下:
Object[] array/ Object[][] array:待插入的一维、二维数组int firstRow:起始行索引(从 1 开始)int firstColumn:起始列索引(从 1 开始)boolean isVertical:一维数组插入方向false:水平插入(从左到右)true:垂直插入(从上到下)Java 代码示例:
import com.spire.xls.*;
public class WriteArrayToWorksheet {
public static void main(String[] args) {
// 创建 Workbook 实例
Workbook workbook = new Workbook();
// 获取第一个工作表
Worksheet worksheet = workbook.getWorksheets().get(0);
// 创建一维数组
Object[] oneDimensionalArray = {"一月", "二月", "三月", "四月", "五月", "六月"};
// 将一维数组写入工作表第一行
worksheet.insertArray(oneDimensionalArray, 1, 1, false);
// 创建二维数组
Object[][] twoDimensionalArray = {
{"姓名", "年龄", "性别", "部门", "电话"},
{"Bob", "25", "男", "技术部", "654214"},
{"John", "24", "男", "广告部", "624847"},
{"Kelly", "26", "女", "销售部", "624758"}
};
// 将二维数组从 A3 单元格开始写入工作表
worksheet.insertArray(twoDimensionalArray, 3, 1);
// 为第一行和第三行应用样式
CellStyle style = workbook.getStyles().addStyle("newStyle");
style.getFont().isBold(true); // 设置字体为粗体
worksheet.getRange().get(1,1,1,6).setStyle(style);
worksheet.getRange().get(3,1,3,6).setStyle(style);
// 保存为 Excel 文件
workbook.saveToFile("写入数组.xlsx", ExcelVersion.Version2016);
}
}
适用场景:
适用于有序数据(例如库存日志、用户列表)的批量插入场景。
效果预览:

若数据存储在 DataTable 中(例如来自数据库的数据),Spire.XLS 可通过 insertDataTable() 方法直接将其导出到 Excel,并保留数据结构和列标题。
核心 API:insertDataTable() 解析
insertDataTable() 是专用于向 Excel 工作表中批量插入结构化数据集的方法,其参数说明如下:
DataTable dataTable:待导出的 DataTable 对象boolean columnHeaders:是否将 DataTable 的列名作为 Excel 表头int firstRow:起始行索引(从 1 开始)int firstColumn:起始列索引(从 1 开始)boolean transTypes:是否保留数据类型Java 代码示例:
import com.spire.xls.*;
import com.spire.xls.data.table.DataRow;
import com.spire.xls.data.table.DataTable;
public class WriteDataTableToWorksheet {
public static void main(String[] args) throws Exception {
// 创建 Workbook 实例
Workbook workbook = new Workbook();
// 获取第一个工作表
Worksheet worksheet = workbook.getWorksheets().get(0);
// 创建 DataTable 对象
DataTable dataTable = new DataTable();
dataTable.getColumns().add("SKU", Integer.class); // 库存单位(SKU)
dataTable.getColumns().add("产品名", String.class); // 产品名称
dataTable.getColumns().add("价格", String.class); // 价格
// 创建数据行并添加数据
DataRow dr = dataTable.newRow();
dr.setInt(0, 512900512);
dr.setString(1,"无线鼠标M200");
dr.setString(2,"¥99");
dataTable.getRows().add(dr);
dr = dataTable.newRow();
dr.setInt(0,512900637);
dr.setString(1,"B100有线鼠标");
dr.setString(2,"¥85");
dataTable.getRows().add(dr);
dr = dataTable.newRow();
dr.setInt(0,512901829);
dr.setString(1,"游戏鼠标");
dr.setString(2,"¥125");
dataTable.getRows().add(dr);
dr = dataTable.newRow();
dr.setInt(0,512900386);
dr.setString(1,"ZM光电鼠标");
dr.setString(2,"¥89");
dataTable.getRows().add(dr);
// 将DataTable写入工作表
worksheet.insertDataTable(dataTable,true,1,1,true);
// 为第一行应用样式
CellStyle style = workbook.getStyles().addStyle("newStyle");
style.getFont().isBold(true); // 设置字体为粗体
worksheet.getRange().get(1,1,1,3).setStyle(style);
// 保存为Excel文件
workbook.saveToFile("写入DataTable.xlsx", ExcelVersion.Version2016);
}
}
适用场景:
适用于导出数据库数据、客户关系管理(CRM)数据,或任何存储在 DataTable 中的结构化数据(例如 SQL 查询结果、CSV 导入数据)。
效果预览:

当处理超大型数据时,需通过以下手段减少内存占用、提升速度:
insertArray() 或 insertDataTable()),而非逐个单元格写入。答:Spire.XLS for Java 支持所有主流 Excel 格式,包括:
可通过 saveToFile() 方法指定输出格式。
答:Spire.XLS 提供了丰富的样式设置功能,可参考以下指南:
答:需申请免费试用许可证,步骤如下:
com.spire.xls.license.LicenseProvider.setLicenseKey("许可证密钥");
Workbook workbook = new Workbook();
对于数据驱动应用中的 Java 开发者而言,掌握 Excel 导出功能至关重要。Spire.XLS for Java 库提供了 3 种通过 Java 向 Excel 写入数据的高效方法:
结合本文的性能优化技巧,可轻松应对从简单报表到大型数据导出的各类需求。若需进一步探索高级功能(如公式计算、图表插入),可参考 Spire.XLS 官网的教程示例。