Spire.XLS 15.4.0 已发布。本次更新新增支持十余个公式,如 RANK.AVG、PERCENTILE.INC 和 BINOM.DIST。同时,该版本还增强了 Excel 到 PDF 的转换功能。此外,许多已知问题也在该版本中成功修复,如保存 Excel 文档后,结构保护密码丢失的问题。详情请阅读以下内容。
新功能:
workbook.Worksheets[0].Range["E9"].Formula = "=RANK.AVG(10,A1:A6)";//Default descending order
workbook.Worksheets[0].Range["E9"].Formula = "=RANK.EQ(10,A1:A6)";workbook.Worksheets[0].Range["D2"].Formula = "=PERCENTILE.INC(\"\", 0.3)";workbook.Worksheets[0].Range["D2"].Formula = "=PERCENTILE.EXC(\"\", 0.3)";workbook.Worksheets[0].Range["D2"].Formula = "=BINOM.DIST(A7, A11, A12, FALSE)";workbook.Worksheets[0].Range["D2"].Formula = "=BINOM.INV(A7, A12, A13)";workbook.Worksheets[0].Range["C10"].Formula = "=NEGBINOM.DIST(10,5,1,TRUE)";workbook.Worksheets[0].Range["C6"].Formula = "=BINOM.DIST.RANGE(10, 2, 5)";workbook.Worksheets[0].Range["C7"].Formula = "=BETA.DIST(3, 0, 5, TRUE, 1, 5)";workbook.Worksheets[0].Range["C7"].Formula = "=BETA.INV(0.685470581, 8, -1, 1, 3)";workbook.Worksheets[0].Range["B3"].Formula = "=ROUNDBANK(1245585, -1)";workbook.Worksheets[0].Range["B3"].Formula = "=GAMMA(ss)";workbook.Worksheets[0].Range["B10"].Formula = "=GAMMA.DIST(10.0001131, 9, 0, TRUE)";workbook.Worksheets[0].Range["B10"].Formula = "=GAMMA.INV(0.068094, 0, 2)";workbook.Worksheets[0].Range["J16"].Formula = "=TAKE(A1:F6,3)";workbook.Worksheets[0].Range["G26"].Formula = "=HSTACK(E1:F7,G1:G6)";问题修复:
在数字化办公场景中,文档的处理往往需要跨平台协作进行。例如,分析人员使用 Excel 处理复杂数据,而最终报告生成则可能需要在 Word 中完成。当文档创建者需要在这些文档之间进行数据转移时,手动复制粘贴不仅效率低下,还容易导致数据错漏、版本冲突和格式错乱。基于 Python 的自动化解决方案能够完美整合 Excel 的数据处理能力与 Word 的格式控制功能,有效保障数据一致性,减少重复排版工作,显著提升财务报告、学术论文、合规文档等场景的生成效率。
本文将介绍如何使用 Spire.Office for Python 通过 Python 代码将 Excel 表格插入到 Word 文档中。
本教程需要 Spire.Office for Python 和 plum-dispatch v1.7.4。您可以下载 Spire.Office for Python 并手动导入到项目,通过以下 pip 命令将它们轻松安装到项目。
pip install Spire.Doc
借助 Spire.XLS for Python,开发者可以使用 CellRange.NumberText 属性从 Excel 工作表中提取数据,并保留数值格式。接下来,开发者可以使用 Spire.Doc for Python 在 Word 文档中创建表格,并使用将数据插入其中。此方法适用于简单的 Excel 工作表以及需要重新格式化表格的情况。
从 Excel 工作表读取数据并写入 Word 表格的步骤:
from spire.doc import Document, AutoFitBehaviorType, FileFormat, DefaultTableStyle
from spire.xls import Workbook
# 指定文件名
excel_file = "Sample.xlsx"
word_file = "output/ExcelDataToWord.docx"
# 创建 Workbook 实例
workbook = Workbook()
# 加载 Excel 文件
workbook.LoadFromFile(excel_file)
# 获取第一个工作表
sheet = workbook.Worksheets.get_Item(0)
# 获取第一个工作表中已使用的单元格范围
allocatedRange = sheet.AllocatedRange
# 创建 Document 实例
doc = Document()
# 向文档添加节,并在该节中添加表格
section = doc.AddSection()
table = section.AddTable()
# 重置 Word 表格的行数和列数,以匹配 Excel 工作表的行数和列数
table.ResetCells(allocatedRange.RowCount, allocatedRange.ColumnCount)
# 遍历已使用的单元格范围的每一行和每一列
for rowIndex in range(allocatedRange.RowCount):
# 遍历当前行中的每一列
for colIndex in range(allocatedRange.ColumnCount):
# 向 Word 表格添加单元格,并在单元格中添加段落
cell = table.Rows.get_Item(rowIndex).Cells.get_Item(colIndex)
paragraph = cell.AddParagraph()
# 将单元格的值追加到 Word 表格,并设置文本格式
textRange = paragraph.AppendText(allocatedRange.get_Item(rowIndex + 1, colIndex + 1).NumberText)
textRange.CharacterFormat.FontName = "HarmonyOS Sans SC"
# 自动调整表格宽度以适应窗口,并应用表格样式
table.AutoFit(AutoFitBehaviorType.AutoFitToWindow)
table.ApplyStyle(DefaultTableStyle.GridTable1LightAccent6)
# 保存 Word 文档
doc.SaveToFile(word_file, FileFormat.Docx2019)
# 释放资源
doc.Dispose()
workbook.Dispose()

开发者也可以使用 Spire.XLS for Python 和 Spire.Doc for Python 同时将 Excel 工作表的数据及单元格格式复制到对应的 Word 文档表格中,从而在移动数据的同时保持 Excel 表格的原有结构和设计。
实现表格结构和设计的保留需要自定义以下方法:
复制 Excel 工作表数据及格式到 Word 表格的步骤:
from spire.xls import Workbook, HorizontalAlignType, ExcelPatternType, VerticalAlignType
from spire.doc import Document, Color, HorizontalAlignment, VerticalAlignment, PageOrientation, FileFormat
def MergeCells(worksheet, wordTable):
# 检查是否存在合并单元格
if not worksheet.HasMergedCells:
return
for cell_range in worksheet.MergedCells:
start_row, start_col = cell_range.Row, cell_range.Column
row_count, col_count = cell_range.RowCount, cell_range.ColumnCount
# 处理水平合并
if col_count > 1:
for row in range(start_row, start_row + row_count):
wordTable.ApplyHorizontalMerge(row - 1, start_col - 1, start_col - 1 + col_count - 1)
# 处理垂直合并
if row_count > 1:
wordTable.ApplyVerticalMerge(start_col - 1, start_row - 1, start_row - 1 + row_count - 1)
def CopyFormatting(tableTextRange, excelCell, wordCell):
# 复制字体样式
font = excelCell.Style.Font
tableTextRange.CharacterFormat.TextColor = Color.FromRgb(font.Color.R, font.Color.G, font.Color.B)
tableTextRange.CharacterFormat.FontSize = float(font.Size)
tableTextRange.CharacterFormat.FontName = font.FontName
tableTextRange.CharacterFormat.Bold = font.IsBold
tableTextRange.CharacterFormat.Italic = font.IsItalic
# 复制背景颜色
if excelCell.Style.FillPattern != ExcelPatternType.none:
wordCell.CellFormat.BackColor = Color.FromRgb(excelCell.Style.Color.R, excelCell.Style.Color.G,
excelCell.Style.Color.B)
# 复制水平对齐方式
hAlignMap = {
HorizontalAlignType.Left: HorizontalAlignment.Left,
HorizontalAlignType.Center: HorizontalAlignment.Center,
HorizontalAlignType.Right: HorizontalAlignment.Right
}
if excelCell.HorizontalAlignment in hAlignMap:
tableTextRange.OwnerParagraph.Format.HorizontalAlignment = hAlignMap[excelCell.HorizontalAlignment]
# 复制垂直对齐方式
vAlignMap = {
VerticalAlignType.Top: VerticalAlignment.Top,
VerticalAlignType.Center: VerticalAlignment.Middle,
VerticalAlignType.Bottom: VerticalAlignment.Bottom
}
if excelCell.VerticalAlignment in vAlignMap:
wordCell.CellFormat.VerticalAlignment = vAlignMap[excelCell.VerticalAlignment]
# 指定文件名
excelFileName = "Sample.xlsx"
wordFileName = "output/ExcelDataFormatToWord.docx"
# 创建 Workbook 实例并加载 Excel 文件
workbook = Workbook()
workbook.LoadFromFile(excelFileName)
# 获取工作表
sheet = workbook.Worksheets.get_Item(0)
# 创建 Document 实例
doc = Document()
# 向文档添加节,并设置页面方向
section = doc.AddSection()
section.PageSetup.Orientation = PageOrientation.Landscape
# 向节中添加表格
table = section.AddTable()
# 根据 Excel 工作表的行数和列数设置表格的行列数
table.ResetCells(sheet.LastRow, sheet.LastColumn)
# 执行 MergeCells 方法合并单元格
MergeCells(sheet, table)
# 遍历 Excel 工作表的每一行和每一列
for r in range(1, sheet.LastRow + 1):
tableRow = table.Rows.get_Item(r - 1)
tableRow.Height = float(sheet.Rows.get_Item(r - 1).RowHeight)
for c in range(1, sheet.LastColumn + 1):
# 获取 Excel 工作表中的单元格和 Word 表格中的单元格
eCell = sheet.Range.get_Item(r, c)
wCell = table.Rows.get_Item(r - 1).Cells.get_Item(c - 1)
# 将单元格的值追加到 Word 表格
textRange = wCell.AddParagraph().AppendText(eCell.NumberText)
# 复制单元格格式
CopyFormatting(textRange, eCell, wCell)
# 保存 Word 文档
doc.SaveToFile(wordFileName, FileFormat.Docx2019)
doc.Dispose()
workbook.Dispose()

除了复制数据和格式之外,开发者还可以直接将 Excel 工作表作为 OLE 对象嵌入到 Word 文档中。此方法不仅能够完整显示工作表内容,还允许用户直接在 Word 文档中编辑 Excel 工作表,并实时更新工作表展示效果。
Spire.Doc for Python 提供的 Paragraph.AppendOleObject(str: filename, DocPicture, OleObjectType.ExcelWorksheet) 方法,可以帮助开发者轻松将 Excel 文件作为 OLE 对象嵌入到 Word 文档中。
插入 Excel 工作表 OLE 对象到 Word 文档的步骤:
from spire.doc import Document, DocPicture, FileFormat, OleObjectType
from spire.xls import Workbook
# 指定文件路径和文件名
excelFileName = "Sample.xlsx"
wordFileName = "output/ExcelOleToWord.docx"
tempImageName = "SheetImage.png"
# 创建 Workbook 实例并加载 Excel 文件
workbook = Workbook()
workbook.LoadFromFile(excelFileName)
# 将第一个工作表保存为图像
sheet = workbook.Worksheets.get_Item(0)
sheet.ToImage(1, 1, sheet.LastRow, sheet.LastColumn).Save(tempImageName)
# 创建 Document 实例以生成 Word 文档
doc = Document()
# 向文档添加节,并在该节中添加段落
section = doc.AddSection()
paragraph = section.AddParagraph()
# 创建 DocPicture 实例并加载图像
pic = DocPicture(doc)
pic.LoadImage(tempImageName)
# 设置图像宽度
pic.Width = section.PageSetup.PageSize.Width - section.PageSetup.Margins.Left - section.PageSetup.Margins.Right
# 将 Excel 文件作为 OLE 对象插入到 Word 文档,并设置已保存的图像作为显示图片
ole = paragraph.AppendOleObject(excelFileName, pic, OleObjectType.ExcelWorksheet)
# 设置为不以图标显示 OLE 对象
ole.DisplayAsIcon = False
# 保存 Word 文档
doc.SaveToFile(wordFileName, FileFormat.Docx2019)
workbook.Dispose()
doc.Dispose()

如果您需要去除生成文档中的评估提示或解除功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
Spire.XLS for Java 15.4.0 现已正式发布。最新版本支持使用表格数据添加 Slicer 切片器。此外,本次升级还成功修复了一些已知问题,比如,Excel 转 XLSB 格式后,OLE 对象打开不正确的问题。更多详情请查阅以下内容。
新功能:
Workbook wb = new Workbook();
//Get the first worksheet of workbook
Worksheet worksheet = wb.getWorksheets().get(0);
worksheet.getRange().get("A1").setValue("fruit");
worksheet.getRange().get("A2").setValue("grape");
worksheet.getRange().get("A3").setValue("blueberry");
worksheet.getRange().get("A4").setValue("kiwi");
worksheet.getRange().get("A5").setValue("cherry");
worksheet.getRange().get("A6").setValue("grape");
worksheet.getRange().get("A7").setValue("blueberry");
worksheet.getRange().get("A8").setValue("kiwi");
worksheet.getRange().get("A9").setValue("cherry");
worksheet.getRange().get("B1").setValue("year");
worksheet.getRange().get("B2").setValue2(2020);
worksheet.getRange().get("B3").setValue2(2020);
worksheet.getRange().get("B4").setValue2(2020);
worksheet.getRange().get("B5").setValue2(2020);
worksheet.getRange().get("B6").setValue2(2021);
worksheet.getRange().get("B7").setValue2(2021);
worksheet.getRange().get("B8").setValue2(2021);
worksheet.getRange().get("B9").setValue2(2021);
worksheet.getRange().get("C1").setValue("amount");
worksheet.getRange().get("C2").setValue2(50);
worksheet.getRange().get("C3").setValue2(60);
worksheet.getRange().get("C4").setValue2(70);
worksheet.getRange().get("C5").setValue2(80);
worksheet.getRange().get("C6").setValue2(90);
worksheet.getRange().get("C7").setValue2(100);
worksheet.getRange().get("C8").setValue2(110);
worksheet.getRange().get("C9").setValue2(120);
//Get slicer collection
XlsSlicerCollection slicers = worksheet.getSlicers();
//Create a super table with the data from the specific cell range.
IListObject table = worksheet.getListObjects().create("Super Table", worksheet.getRange().get("A1:C9"));
int count = 3;
int index = 0;
for (Object styletype : SlicerStyleType.values())
{
SlicerStyleType type = (SlicerStyleType)styletype;
count += 5;
//Add a Slicer through pivot table data : here invoke Add(IListObject, string, int) api.
String range = "E" + count;
index = slicers.add(table, range.toString(), 0);
//Style setting
XlsSlicer xlsSlicer = slicers.get(index);
xlsSlicer.setName("slicers_" + count);
xlsSlicer.setStyleType(type);
}
//Save to file
wb.saveToFile(outputFile_xlsx, ExcelVersion.Version2013);Workbook wb = new Workbook();
//Get the first worksheet of workbook
Worksheet worksheet = wb.getWorksheets().get(0);
worksheet.getRange().get("A1").setValue("fruit");
worksheet.getRange().get("A2").setValue("grape");
worksheet.getRange().get("A3").setValue("blueberry");
worksheet.getRange().get("A4").setValue("kiwi");
worksheet.getRange().get("A5").setValue("cherry");
worksheet.getRange().get("A6").setValue("grape");
worksheet.getRange().get("A7").setValue("blueberry");
worksheet.getRange().get("A8").setValue("kiwi");
worksheet.getRange().get("A9").setValue("cherry");
worksheet.getRange().get("B1").setValue("year");
worksheet.getRange().get("B2").setValue2(2020);
worksheet.getRange().get("B3").setValue2(2020);
worksheet.getRange().get("B4").setValue2(2020);
worksheet.getRange().get("B5").setValue2(2020);
worksheet.getRange().get("B6").setValue2(2021);
worksheet.getRange().get("B7").setValue2(2021);
worksheet.getRange().get("B8").setValue2(2021);
worksheet.getRange().get("B9").setValue2(2021);
worksheet.getRange().get("C1").setValue("amount");
worksheet.getRange().get("C2").setValue2(50);
worksheet.getRange().get("C3").setValue2(60);
worksheet.getRange().get("C4").setValue2(70);
worksheet.getRange().get("C5").setValue2(80);
worksheet.getRange().get("C6").setValue2(90);
worksheet.getRange().get("C7").setValue2(100);
worksheet.getRange().get("C8").setValue2(110);
worksheet.getRange().get("C9").setValue2(120);
// Get pivot table collection
PivotTablesCollection pivotTables = worksheet.getPivotTables();
//Add a PivotTable to the worksheet
CellRange dataRange = worksheet.getRange().get("A1:C9");
PivotCache cache = wb.getPivotCaches().add(dataRange);
//Cell to put the pivot table
PivotTable pt = worksheet.getPivotTables().add("TestPivotTable", worksheet.getRange().get("A12"), cache);
//Drag the fields to the row area.
IPivotField pf = pt.getPivotFields().get("fruit");
pf.setAxis(AxisTypes.Row);
IPivotField pf2 = pt.getPivotFields().get("year");
pf2.setAxis(AxisTypes.Column);
//Drag the field to the data area.
pt.getDataFields().add(pt.getPivotFields().get("amount"), "SUM of Count", SubtotalTypes.Sum);
//Set PivotTable style
pt.setBuiltInStyle(PivotBuiltInStyles.PivotStyleMedium10);
//Get slicer collection
XlsSlicerCollection slicers = worksheet.getSlicers();
//Add a Slicer through pivot table data: here invoke Add(IPivotTable, string, int) api.
int index = slicers.add(pt, "E12", 0);
XlsSlicer xlsSlicer = slicers.get(index);
xlsSlicer.setName("test_xlsSlicer");
xlsSlicer.setWidth(100);
xlsSlicer.setHeight(120);
xlsSlicer.setStyleType(SlicerStyleType.SlicerStyleLight2);
xlsSlicer.isPositionLocked(true);
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache = xlsSlicer.getSlicerCache();
slicerCache.setCrossFilterType(SlicerCacheCrossFilterType.ShowItemsWithNoData);
//Style setting
XlsSlicerCacheItemCollection slicerCacheItems = xlsSlicer.getSlicerCache().getSlicerCacheItems();
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems.get(0);
xlsSlicerCacheItem.isSelected(false);
XlsSlicerCollection slicers_2 = worksheet.getSlicers();
IPivotField r1 = pt.getPivotFields().get("year");
int index_2 = slicers_2.add(pt, "I12", r1);
XlsSlicer xlsSlicer_2 = slicers.get(index_2);
xlsSlicer_2.setRowHeight(40);
xlsSlicer_2.setStyleType(SlicerStyleType.SlicerStyleLight3);
xlsSlicer_2.isPositionLocked(false);
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache_2 = xlsSlicer_2.getSlicerCache();
slicerCache_2.setCrossFilterType(SlicerCacheCrossFilterType.ShowItemsWithDataAtTop);
//Style setting
XlsSlicerCacheItemCollection slicerCacheItems_2 = xlsSlicer_2.getSlicerCache().getSlicerCacheItems();
XlsSlicerCacheItem xlsSlicerCacheItem_2 = slicerCacheItems_2.get(1);
xlsSlicerCacheItem_2.isSelected(false);
pt.calculateData();
//Save to file
wb.saveToFile("out.xlsx", ExcelVersion.Version2013);Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
//Get slicer collection of first worksheet
Worksheet worksheet_1 = wb.getWorksheets().get(0);
XlsSlicerCollection slicers = worksheet_1.getSlicers();
// Remove the first slicer by index
slicers.removeAt(0);
XlsSlicer slicer = worksheet_1.getSlicers().get(1);
// Remove second slicer by object
worksheet_1.getSlicers().remove(slicer);
Worksheet worksheet_2 = wb.getWorksheets().get(2);
// Remove all slicers
worksheet_2.getSlicers().clear();
//Save to file
wb.saveToFile(outputFile_xlsx, ExcelVersion.Version2013);Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
//Get the first worksheet of workbook
Worksheet worksheet = wb.getWorksheets().get(0);
// Get slicer collection
XlsSlicerCollection slicers = worksheet.getSlicers();
//Style setting
XlsSlicer xlsSlicer = slicers.get(0);
xlsSlicer.setStyleType(SlicerStyleType.SlicerStyleDark4);
xlsSlicer.setCaption("Slicer");
xlsSlicer.isPositionLocked(true);
XlsSlicerCacheItemCollection slicerCacheItems = xlsSlicer.getSlicerCache().getSlicerCacheItems();
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems.get(0);
xlsSlicerCacheItem.isSelected(false);
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache = xlsSlicer.getSlicerCache();
slicerCache.setCrossFilterType(SlicerCacheCrossFilterType.ShowItemsWithNoData);
//Save to file
wb.saveToFile(outputFile_xlsx, ExcelVersion.Version2013);Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
// Get slicer collection of first worksheet
Worksheet worksheet = wb.getWorksheets().get(0);
XlsSlicerCollection slicers = worksheet.getSlicers();
StringBuilder builder = new StringBuilder();
builder.append("slicers.Count:" + slicers.getCount()+"\r\n");
XlsSlicer xlsSlicer = slicers.get(1);
builder.append("xlsSlicer.Name:" + xlsSlicer.getName()+"\r\n");
builder.append("xlsSlicer.Caption:" + xlsSlicer.getCaption()+"\r\n");
builder.append("xlsSlicer.NumberOfColumns:" + xlsSlicer.getNumberOfColumns()+"\r\n");
builder.append("xlsSlicer.ColumnWidth:" + xlsSlicer.getColumnWidth()+"\r\n");
builder.append("xlsSlicer.RowHeight:" + xlsSlicer.getRowHeight()+"\r\n");
builder.append("xlsSlicer.ShowCaption:" + xlsSlicer.isShowCaption()+"\r\n");
builder.append("xlsSlicer.PositionLocked:" + xlsSlicer.isPositionLocked()+"\r\n");
builder.append("xlsSlicer.Width:" + xlsSlicer.getWidth()+"\r\n");
builder.append("xlsSlicer.Height:" + xlsSlicer.getHeight()+"\r\n");
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache = xlsSlicer.getSlicerCache();
builder.append("slicerCache.SourceName:" + slicerCache.getSourceName()+"\r\n");
builder.append("slicerCache.IsTabular:" + slicerCache.isTabular()+"\r\n");
builder.append("slicerCache.Name:" + slicerCache.getName()+"\r\n");
XlsSlicerCacheItemCollection slicerCacheItems = slicerCache.getSlicerCacheItems();
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems.get(1);
builder.append("xlsSlicerCacheItem.Selected:" + xlsSlicerCacheItem.isSelected() +"\r\n");
FileWriter fw = new FileWriter(outputFile_T);
fw.write(builder.toString());
fw.flush();
fw.close();
wb.dispose();问题修复:
Spire.Doc for Java 13.4.1 现已正式发布。该版本增强了 Word 到 HTML 和 PDF 的转换,还修复了一些在读取内容和获取 OLE 的 NativeDatabytes 时出现的问题。 更多详情如下。
问题修复:
折线图是一种通过直线连接数据点来展示信息的图表,特别适用于显示随时间变化的趋势。例如,在跟踪每月销售数据时,折线图可以帮助识别趋势、峰值和低谷。在本文中,您将学习如何使用 Spire.XLS for Python 通过 Python 在 Excel 中创建折线图。
本教程需要 Spire.XLS for Python 和 plum-dispatch v1.7.4。您可以通过以下 pip 命令将它们轻松安装到 Windows 中。
pip install Spire.XLS
如果您不确定如何安装,请参考此教程: 如何在 Windows 中安装 Spire.XLS for Python
如果想要观察年度销售数据的走势、气温变化或者股价的走势,您可以使用简单折线图来呈现。Spire.XLS for Python 提供了 Worksheet.Charts.Add(ExcelChartType.Line) 方法,可帮助您在 Excel 工作表中快速添加简单折线图。
创建简单折线图的具体步骤如下:
from spire.xls import *
from spire.xls.common import *
# 创建一个 Workbook 类的实例
workbook = Workbook()
# 获取第一个工作表并设置其名称
sheet = workbook.Worksheets[0]
sheet.Name = "折线图"
# 添加数据到指定单元格
sheet.Range["A1"].Value = "目录"
sheet.Range["A2"].Value = "水果"
sheet.Range["A3"].Value = "饮料"
sheet.Range["A4"].Value = "饼干"
sheet.Range["B1"].Value = "一月"
sheet.Range["B2"].NumberValue = 173
sheet.Range["B3"].NumberValue = 189
sheet.Range["B4"].NumberValue = 153
sheet.Range["C1"].Value = "二月"
sheet.Range["C2"].NumberValue = 151
sheet.Range["C3"].NumberValue = 165
sheet.Range["C4"].NumberValue = 201
sheet.Range["D1"].Value = "三月"
sheet.Range["D2"].NumberValue = 147
sheet.Range["D3"].NumberValue = 112
sheet.Range["D4"].NumberValue = 168
sheet.Range["E1"].Value = "四月"
sheet.Range["E2"].NumberValue = 140
sheet.Range["E3"].NumberValue = 109
sheet.Range["E4"].NumberValue = 124
sheet.Range["F1"].Value = "五月"
sheet.Range["F2"].NumberValue = 131
sheet.Range["F3"].NumberValue = 161
sheet.Range["F4"].NumberValue = 188
sheet.Range["G1"].Value = "六月"
sheet.Range["G2"].NumberValue = 174
sheet.Range["G3"].NumberValue = 153
sheet.Range["G4"].NumberValue = 136
# 设置单元格样式
sheet.Range["A1:G1"].RowHeight = 20
sheet.Range["A1:G1"].Style.Color = Color.get_Black()
sheet.Range["A1:G1"].Style.Font.Color = Color.get_White()
sheet.Range["A1:G1"].Style.Font.IsBold = True
sheet.Range["A1:G1"].Style.Font.Size = 11
sheet.Range["A1:G1"].Style.VerticalAlignment = VerticalAlignType.Center
sheet.Range["A1:G1"].Style.HorizontalAlignment = HorizontalAlignType.Center
sheet.Range["B2:G4"].Style.NumberFormat = "\"¥\"#,##0"
# 在工作表中添加折线图
chart = sheet.Charts.Add(ExcelChartType.Line)
# 设置图表数据范围
chart.DataRange = sheet.Range["A1:G4"]
# 设置图表的位置
chart.LeftColumn = 1
chart.TopRow = 6
chart.RightColumn = 12
chart.BottomRow = 27
# 设置并格式化图表标题
chart.ChartTitle = "月消耗物资"
chart.ChartTitleArea.IsBold = True
chart.ChartTitleArea.Size = 12
# 设置图表类别轴
chart.PrimaryCategoryAxis.Title = "月"
chart.PrimaryCategoryAxis.Font.IsBold = True
chart.PrimaryCategoryAxis.TitleArea.IsBold = True
# 设置图表值轴
chart.PrimaryValueAxis.Title = "数量"
chart.PrimaryValueAxis.HasMajorGridLines = False
chart.PrimaryValueAxis.TitleArea.TextRotationAngle = 90
chart.PrimaryValueAxis.MinValue = 100
chart.PrimaryValueAxis.TitleArea.IsBold = True
# 设置系列颜色和数据标签
for cs in chart.Series:
cs.Format.Options.IsVaryColor = True
cs.DataPoints.DefaultDataPoint.DataLabels.HasValue = True
# 设置图例位置
chart.Legend.Position = LegendPositionType.Top
# 保存文件
workbook.SaveToFile("/简单折线图.xlsx", ExcelVersion.Version2016)
workbook.Dispose()

堆积折线图通过将每个类别的值堆叠在一起,强调整体的总量变化,使数据系列对整体趋势的贡献更加直观。比如不同部门的销售额对公司总收入的贡献,各渠道(线上、线下、代理)的销售额合计变化等。
以下是在 Python 中创建堆积折线图的步骤:
from spire.xls import *
from spire.xls.common import *
# 创建一个 Workbook 类的实例
workbook = Workbook()
# 获取第一个工作表并设置其名称
sheet = workbook.Worksheets[0]
sheet.Name = "折线图"
# 将数据填入指定单元格
sheet.Range["A1"].Value = "目录"
sheet.Range["A2"].Value = "水果"
sheet.Range["A3"].Value = "饮料"
sheet.Range["A4"].Value = "饼干"
sheet.Range["B1"].Value = "一月"
sheet.Range["B2"].NumberValue = 173
sheet.Range["B3"].NumberValue = 189
sheet.Range["B4"].NumberValue = 153
sheet.Range["C1"].Value = "二月"
sheet.Range["C2"].NumberValue = 151
sheet.Range["C3"].NumberValue = 165
sheet.Range["C4"].NumberValue = 201
sheet.Range["D1"].Value = "三月"
sheet.Range["D2"].NumberValue = 147
sheet.Range["D3"].NumberValue = 112
sheet.Range["D4"].NumberValue = 168
sheet.Range["E1"].Value = "四月"
sheet.Range["E2"].NumberValue = 140
sheet.Range["E3"].NumberValue = 109
sheet.Range["E4"].NumberValue = 124
sheet.Range["F1"].Value = "五月"
sheet.Range["F2"].NumberValue = 131
sheet.Range["F3"].NumberValue = 161
sheet.Range["F4"].NumberValue = 188
sheet.Range["G1"].Value = "六月"
sheet.Range["G2"].NumberValue = 174
sheet.Range["G3"].NumberValue = 153
sheet.Range["G4"].NumberValue = 136
# 设置单元格样式
sheet.Range["A1:G1"].RowHeight = 20
sheet.Range["A1:G1"].Style.Color = Color.get_Black()
sheet.Range["A1:G1"].Style.Font.Color = Color.get_White()
sheet.Range["A1:G1"].Style.Font.IsBold = True
sheet.Range["A1:G1"].Style.Font.Size = 11
sheet.Range["A1:G1"].Style.VerticalAlignment = VerticalAlignType.Center
sheet.Range["A1:G1"].Style.HorizontalAlignment = HorizontalAlignType.Center
sheet.Range["B2:G4"].Style.NumberFormat = "\"¥\"#,##0"
# 将堆叠折线图添加到工作表中
chart = sheet.Charts.Add(ExcelChartType.LineStacked)
# 设置图表数据范围
chart.DataRange = sheet.Range["A1:G4"]
# 设置图表的位置
chart.LeftColumn = 1
chart.TopRow = 6
chart.RightColumn = 12
chart.BottomRow = 27
# 设置图表的标题
chart.ChartTitle = "月消耗物资"
chart.ChartTitleArea.IsBold = True
chart.ChartTitleArea.Size = 12
# 设置图表的分类轴
chart.PrimaryCategoryAxis.Title = "月"
chart.PrimaryCategoryAxis.Font.IsBold = True
chart.PrimaryCategoryAxis.TitleArea.IsBold = True
# 设置图表的值轴
chart.PrimaryValueAxis.Title = "数量"
chart.PrimaryValueAxis.HasMajorGridLines = False
chart.PrimaryValueAxis.TitleArea.TextRotationAngle = 90
chart.PrimaryValueAxis.TitleArea.IsBold = True
# 设置图表系列颜色和数据标签
for cs in chart.Series:
cs.Format.Options.IsVaryColor = True
cs.DataPoints.DefaultDataPoint.DataLabels.HasValue = True
# 设置图例位置
chart.Legend.Position = LegendPositionType.Top
# 保存结果文档
workbook.SaveToFile("/堆叠折线图.xlsx", ExcelVersion.Version2016)
workbook.Dispose()

如果您需要去除生成文档中的评估提示或解除功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
在处理 Word 文档时,字体管理往往是一项繁琐的工作,尤其是当文件较大或需要处理多个文档时。如果您希望统一文档中的字体,或者修复字体不一致的问题,掌握高效的字体检索与替换方法将非常有用。本指南将介绍如何使用 Spire.Doc for Python 来自动化字体的获取与替换流程,提高文档处理效率。
本教程需要 Spire.Doc for Python 和 plum-dispatch v1.7.4。您可以通过以下 pip 命令将它们轻松安装到 Windows 中。
pip install Spire.Doc
如果您不确定如何安装,请参考此教程: 如何在 Windows 中安装 Spire.Doc for Python
想要从 Word 文档中提取字体信息,需要遍历文档的各个节、段落及其子对象。在检查子对象时,需要查找其中是否包含 TextRange 类的实例,如果有,就可以通过 CharacterFormat 属性获取字体名称和字号等信息。
使用 Python 读取 Word 文档中的字体信息,具体步骤如下:
from spire.doc import *
from spire.doc.common import *
# 将字符串写为 txt 文件的函数
def WriteAllText(fname:str,text:List[str]):
fp = open(fname,"w", encoding="utf-8")
for s in text:
fp.write(s)
# 自定义 FontInfo 类
class FontInfo:
def __init__(self):
self._m_name = ''
self._m_size = None
def __eq__(self,other):
if isinstance(other,FontInfo):
return self._m_name == other.get_name() and self._m_size == other.get_size()
return False
def get_name(self):
return self._m_name
def set_name(self, value):
self._m_name = value
def get_size(self):
return self._m_size
def set_size(self, value):
self._m_size = value
# 声明变量
fontInformations = ""
font_infos = []
# 创建一个 Document 类的对象
document = Document()
# 加载 Word 文档
document.LoadFromFile("/示例文档.docx")
# 遍历文档的所有节
for i in range(document.Sections.Count):
# 获取当前节
section = document.Sections.get_Item(i)
# 遍历该节中的所有段落
for j in range(section.Body.Paragraphs.Count):
# 获取当前段落
paragraph = section.Body.Paragraphs.get_Item(j)
# 遍历段落中的所有子对象
for k in range(paragraph.ChildObjects.Count):
# 获取指定子对象
obj = paragraph.ChildObjects.get_Item(k)
# 判断子对象是否为文本范围
if isinstance(obj, TextRange):
# 获取指定文本范围
txtRange = obj if isinstance(obj, TextRange) else None
# 获取字体的名称和大小
fontName = txtRange.CharacterFormat.FontName
fontSize = txtRange.CharacterFormat.FontSize
# 获取文本的颜色
textColor = txtRange.CharacterFormat.TextColor.Name
# 将字体信息保存在 fontInformations 变量中
fontInfo = FontInfo()
fontInfo.set_name(fontName)
fontInfo.set_size(fontSize)
if fontInfo not in font_infos:
font_infos.append(fontInfo)
str = "字体名称:{0:s}、字号:{1:f}、字体颜色:{2:s}".format(fontInfo.get_name(), fontInfo.get_size(), textColor)
fontInformations += str
fontInformations += '\r'
# 将字体信息写入 txt 文件
WriteAllText("/获取字体.txt", fontInformations)
document.Dispose()

当获取了特定文本范围的字体名称后,您就可以轻松将其替换为其它字体。要实现这一点,可以使用 TextRange.CharacterFormat.FontName 属性来指定新的字体。此外,您还可以通过 TextRange 类中的相关属性修改字体大小和文本颜色。
使用 Python 在 Word 文档中替换指定字体的具体步骤如下:
from spire.doc import *
from spire.doc.common import *
# 创建一个 Document 类的对象
document = Document()
# 加载 Word 文档
document.LoadFromFile("/示例文档.docx")
# 遍历所有节
for i in range(document.Sections.Count):
# 获取当前节
section = document.Sections.get_Item(i)
# 遍历每一个段落
for j in range(section.Body.Paragraphs.Count):
# 获取指定段落
paragraph = section.Body.Paragraphs.get_Item(j)
# 遍历段落下的所有子对象
for k in range(paragraph.ChildObjects.Count):
# 获取子对象
obj = paragraph.ChildObjects.get_Item(k)
# 检查子对象是否是文本范围
if isinstance(obj, TextRange):
# 获取文本范围
txtRange = obj if isinstance(obj, TextRange) else None
# 获取字体名称
fontName = txtRange.CharacterFormat.FontName
# 检查字体名称是否为 FangSong
if (fontName == "FangSong"):
# 替换为另一个字体
txtRange.CharacterFormat.FontName = "LiSu"
# 保存修改后文档
document.SaveToFile("/替换字体.docx", FileFormat.Docx)
# 释放资源
document.Dispose()

如果您需要去除生成文档中的评估提示或解除功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
在处理 PDF 文件时,常常需要调整页面尺寸,以突出关键信息、去除多余空白或适应特定的打印和显示需求。裁剪 PDF 页面可以帮助优化文档布局,使内容更清晰、排版更紧凑,同时减少文件大小,提高阅读和共享的便利性。此外,合理裁剪页面还能提升文档的视觉美观度,使其更符合专业排版要求。这篇文章将介绍如何使用 Spire.PDF for Java 库在 Java 中裁剪 PDF 页面。
首先,您需要在 Java 程序中添加 Spire.Pdf.jar 文件作为依赖项。JAR 文件可以从此链接下载。 如果您使用 Maven,则可以将以下代码添加到项目的 pom.xml 文件中,从而轻松地在应用程序中导入 JAR 文件。
<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>
Spire.PDF for Java 提供了 PdfPageBase.setCropBox(Rectangle2D rect) 方法,用于设置 PDF 页面的裁剪区域。具体步骤如下:
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import java.awt.geom.Rectangle2D;
public class CropPdfPage {
public static void main(String[] args) {
// 创建 PdfDocument 类的实例
PdfDocument pdf = new PdfDocument();
// 加载 PDF 文件
pdf.loadFromFile("示例.pdf");
// 获取 PDF 的第一页
PdfPageBase page = pdf.getPages().get(0);
// 定义裁剪区域 (参数分别为x, y, 宽度, 高度)
Rectangle2D rectangle = new Rectangle2D.Float(0, 40, 600, 360);
// 设置页面的裁剪区域
page.setCropBox(rectangle);
// 保存裁剪后的 PDF 文件
pdf.saveToFile("裁剪页面.pdf");
// 关闭文件,释放资源
pdf.close();
}
}

在裁剪 PDF 页面后,开发者可以使用 PdfDocument.saveAsImage(int pageIndex, PdfImageType type) 方法将其导出为图片。具体步骤如下:
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.graphics.PdfImageType;
import javax.imageio.ImageIO;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class CropPdfPageAndSaveAsImage {
public static void main(String[] args) {
// 创建 PdfDocument 类的实例
PdfDocument pdf = new PdfDocument();
// 加载 PDF 文件
pdf.loadFromFile("示例.pdf");
// 获取 PDF 的第一页
PdfPageBase page = pdf.getPages().get(0);
// 定义裁剪区域 (参数分别为x, y, 宽度, 高度)
Rectangle2D rectangle = new Rectangle2D.Float(0, 40, 600, 360);
// 设置页面的裁剪区域
page.setCropBox(rectangle);
// 导出裁剪后的页面为图片
BufferedImage image = pdf.saveAsImage(0, PdfImageType.Bitmap);
// 保存图片为 PNG 文件
File outputFile = new File("裁剪.png");
try {
ImageIO.write(image, "PNG", outputFile);
System.out.println("裁剪后的页面已保存为: " + outputFile.getAbsolutePath());
} catch (IOException e) {
System.err.println("保存图片时发生错误: " + e.getMessage());
}
// 关闭文档,释放资源
pdf.close();
}
}

如果您需要去除生成文档中的评估提示或解除功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
在 PDF 文档中添加注释是一种常见的操作,可用于插入评论、突出显示文本、绘制图形等。这项功能在协作审阅、教育领域以及专业演示中尤为实用,它使用户能够直接在电子文档上标注关键信息,从而大幅提升沟通和工作效率。
本文将介绍如何使用 Spire.PDF for Python 在 Python 中给 PDF 文档添加多种类型的注释。
本教程需要用到 Spire.PDF for Python 和 plum-dispatch v1.7.4。可以通过以下 pip 命令将它们轻松安装到 Windows 中。
pip install Spire.PDF
如果您不确定如何安装,请参考:如何在 Windows 中安装 Spire.PDF for Python
文本标注注释用于突出显示 PDF 文档中的重要内容。如果您想添加文本标注注释,首先需要用到 PdfTextFinder 类来查找目标文本。找到文本后,再创建 PdfTextMarkupAnnotation 对象,并将其应用到 PDF 文档中。
以下是使用 Python 向 PDF 添加文本标注注释的步骤:
from spire.pdf.common import *
from spire.pdf import *
# 创建一个 PdfDocument 类的对象
doc = PdfDocument()
# 加载 PDF 文档
doc.LoadFromFile("/示例文档.pdf")
# 获取文档中的一页
page = doc.Pages.get_Item(0)
# 在该页上创建一个 PdfTextFinder 对象
finder = PdfTextFinder(page)
# 设置查找的选项
finder.Options.Parameter = TextFindParameter.WholeWord
# 查找指定文本的实例
fragments = finder.Find("AI绘画的优势和弊端不容忽视,它既为艺术创作带来了前所"+
"未有的机遇,也引发了深刻的社会讨论和法律思考");
# 获取第一个实例
textFragment = fragments[0]
# 自定义注释内容
text = "这是一个文本标注注释"
# 遍历文本边界
for i in range(len(textFragment.Bounds)):
# 获取边界
rect = textFragment.Bounds[i]
# 创建文本标记注释
annotation = PdfTextMarkupAnnotation("Administrator", text, rect)
# 设置标记的颜色
annotation.TextMarkupColor = PdfRGBColor(Color.get_Green())
# 将注释添加到注释集合中
page.AnnotationsWidget.Add(annotation)
# 保存修改后的文档
doc.SaveToFile("/标记注释.pdf")
doc.Dispose()

通过自由文本注释,您可以将自由形式的文本批注直接添加到 PDF 文档中。想要在指定位置添加自由文本注释,您可以使用 PdfTextFinder 类来获取所查找文本的坐标信息,然后根据坐标创建一个 PdfFreeTextAnnotation 对象,最后将其添加到文档中。
以下是在 Python 中向 PDF 添加自由文本注释的步骤:
from spire.pdf.common import *
from spire.pdf import *
# 创建一个 PdfDocument 类的对象
doc = PdfDocument()
# 加载 PDF 文档
doc.LoadFromFile("/示例文档.pdf")
# 获取文档中的一页
page = doc.Pages[0]
# 在该页上创建一个 PdfTextFinder 对象
finder = PdfTextFinder(page)
# 设置查找的选项
finder.Options.Parameter = TextFindParameter.WholeWord
# 查找指定文本的实例
fragments = finder.Find("弊端");
# 获取第一个实例
textFragment = fragments[0]
# 获取文本边界
rect = textFragment.Bounds[0]
# 获取文本边界的坐标以添加注释
right = rect.Right
top = rect.Top
# 创建自由文本注释注释
rectangle = RectangleF(right + 5, top + 2, 160.0, 18.0)
textAnnotation = PdfFreeTextAnnotation(rectangle)
# 设置注释内容
textAnnotation.Text = "这是一个自由文本标注"
# 设置注释的其它属性
font = PdfTrueTypeFont("微软雅黑", 13.0, PdfFontStyle.Italic, True)
border = PdfAnnotationBorder(1.0)
textAnnotation.Font = font
textAnnotation.Border = border
textAnnotation.BorderColor = PdfRGBColor(Color.get_SkyBlue())
textAnnotation.Color = PdfRGBColor(Color.get_LightBlue())
textAnnotation.Opacity = 1.0
# 将注释添加到页面的注释集合中
page.AnnotationsWidget.Add(textAnnotation)
# 保存修改后的文档
doc.SaveToFile("/自由文本注释.pdf")
doc.Dispose()

弹出式注释可以以弹窗的形式展示附加信息或内容。要确定添加弹出注释的位置,仍然可以使用 PdfTextFinder 类来获取坐标信息。在此之后,您可以创建 PdfPopupAnnotation 对象并将其添加到 PDF 文档中。
通过 Python 在 PDF 文档中添加弹出式注释的具体步骤可以参考下方内容:
from spire.pdf.common import *
from spire.pdf import *
# 创建一个 PdfDocument 类的对象
doc = PdfDocument()
# 加载 PDF 文档
doc.LoadFromFile("/示例文档.pdf")
# 获取文档中的一页
page = doc.Pages[0]
# 在该页上创建一个 PdfTextFinder 对象
finder = PdfTextFinder(page)
# 设置查找的选项
finder.Options.Parameter = TextFindParameter.WholeWord
# 查找指定文本的实例
fragments = finder.Find("弊端");
# 获取第一个实例
textFragment = fragments[0]
# 获取文本边界
rect = textFragment.Bounds[0]
# 获取文本边界的坐标以添加注释
right = rect.Right
top = rect.Top
# 创建注释
rectangle = RectangleF(right + 5, top, 30.0, 30.0)
popupAnnotation = PdfPopupAnnotation(rectangle)
# 自定义注释内容
popupAnnotation.Text = "这是一个弹出式的注释"
# 设置注释的图标和颜色
popupAnnotation.Icon = PdfPopupIcon.Comment
popupAnnotation.Color = PdfRGBColor(Color.get_Red())
# 将注释添加到文档的注释集合中
page.AnnotationsWidget.Add(popupAnnotation)
# 保存修改后的文档
doc.SaveToFile("/弹出式注释.pdf")
doc.Dispose()

在 PDF 文档中,印章注释是一种允许用户向 PDF 文件添加自定义“印章”或符号的注释类型。要设置图章注释的外观,可以使用 PdfTemplate 类。然后,创建 PdfRubberStampAnnotation 对象,并将之前自定义的模板设置为其外观,最后将该注释添加到 PDF 文档中。
使用 Python 向 PDF 添加印章注释的步骤如下:
from spire.pdf.common import *
from spire.pdf import *
# 创建一个 PdfDocument 类的对象
doc = PdfDocument()
# 加载 PDF 文档
doc.LoadFromFile("/示例文档.pdf")
# 获取文档中的一页
page = doc.Pages[0]
# 加载一个图像
image = PdfImage.FromFile("/印章.png")
# 设置图像印章的宽度和高度
width = (float)(image.Width*0.5)
height = (float)(image.Height*0.5)
# 根据图像的大小创建一个 PdfTemplate 对象
template = PdfTemplate(width, height, True)
# 在模板上绘制图像
template.Graphics.DrawImage(image, 0.0, 0.0, width, height)
# 创建一个印章注释,设置它在页面上的位置
rect = RectangleF((float) (page.ActualSize.Width/2 - width/2), 90.0, width, height)
stamp = PdfRubberStampAnnotation(rect)
# 创建 PdfAppearance 对象
pdfAppearance = PdfAppearance(stamp)
# 设置模板为注释的默认样式
pdfAppearance.Normal = template
# 将样式应用到注释上
stamp.Appearance = pdfAppearance
# 将注释添加到 PDF 文档中
page.AnnotationsWidget.Add(stamp)
# 保存修改后的文档
doc.SaveToFile("/印章注释.pdf")
doc.Dispose()

在 PDF 文档中,形状注释是一种允许用户向 PDF 文件添加各种几何形状的注释。Spire.PDF for Python 提供了 PdfPolyLineAnnotation、PdfLineAnnotation 和 PdfPolygonAnnotation 等类,使开发者能够向 PDF 文件中添加不同类型的形状注释。
使用 Python 向 PDF 添加形状注释的步骤如下:
from spire.pdf.common import *
from spire.pdf import *
# 创建一个 PdfDocument 类的对象
doc = PdfDocument()
# 加载 PDF 文档
doc.LoadFromFile("/示例文档.pdf")
# 获取文档中的一页
page = doc.Pages[0]
# 在该页上创建一个 PdfTextFinder 对象
finder = PdfTextFinder(page)
# 设置查找的选项
finder.Options.Parameter = TextFindParameter.WholeWord
# 查找指定文本的实例
fragments = finder.Find("AI绘画的优势和弊端不容忽视");
# 获取第一个实例
textFragment = fragments[0]
# 获取文本边界
rect = textFragment.Bounds[0]
# 获取文本边界的坐标以添加注释
left = rect.Left
top = rect.Top
right = rect.Right
bottom = rect.Bottom
# 创建一个形状注释
polyLineAnnotation = PdfPolyLineAnnotation(page, [PointF(left, top), PointF(right, top), PointF(right - 5, bottom), PointF(left - 5, bottom), PointF(left, top)])
# 自定义注释内容
polyLineAnnotation.Text = "这是一个形状注释"
# 将注释添加到文档的注释集合中
page.AnnotationsWidget.Add(polyLineAnnotation)
# 保存修改后的文档
doc.SaveToFile("/形状注释.pdf")
doc.Dispose()

PDF 中的网页链接注释是一种可以嵌入超链接的注释,便于用户访问在线资源或相关信息。您可以使用 PdfTextFinder 类来查找 PDF 文档中的指定文本,并基于该文本创建一个 PdfUriAnnotation 对象,最后将其添加 PDF 文档的特定位置。
使用 Python 向 PDF 添加网页链接注释的详细步骤如下:
from spire.pdf.common import *
from spire.pdf import *
# 创建一个 PdfDocument 类的对象
doc = PdfDocument()
# 加载 PDF 文档
doc.LoadFromFile("/示例文档.pdf")
# 获取文档中的一页
page = doc.Pages[0]
# 在该页上创建一个 PdfTextFinder 对象
finder = PdfTextFinder(page)
# 设置查找的选项
finder.Options.Parameter = TextFindParameter.WholeWord
# 查找指定文本的实例
fragments = finder.Find("AI绘画的优势和弊端不容忽视");
# 获取第一个实例
textFragment = fragments[0]
# 获取文本边界
bound = textFragment.Bounds[0]
# 创建一个 URL 注释
urlAnnotation = PdfUriAnnotation(bound, "https://www.e-iceblue.cn/");
# 将注释添加到文档的注释集合中
page.AnnotationsWidget.Add(urlAnnotation)
# 保存修改后的文档
doc.SaveToFile("/网页链接注释.pdf")
doc.Dispose()

如果您需要在使用 PDF 文档时打开一个外部文件,可以在关键词上添加一个文件链接注释。它可以链接另一个 PDF、图片或文档。在 Python 中,您可以使用 PdfTextFinder 类查找 PDF 文档中的指定文本,并基于该文本创建 PdfFileLinkAnnotation 对象,最后将这个注释添加到页面上的指定位置。
下方是使用 Python 向 PDF 添加文件链接注释的详细步骤:
from spire.pdf.common import *
from spire.pdf import *
# 创建一个 PdfDocument 类的对象
doc = PdfDocument()
# 加载 PDF 文档
doc.LoadFromFile("/示例文档.pdf")
# 获取文档中的一页
page = doc.Pages[0]
# 在该页上创建一个 PdfTextFinder 对象
finder = PdfTextFinder(page)
# 设置查找的选项
finder.Options.Parameter = TextFindParameter.WholeWord
# 查找指定文本的实例
fragments = finder.Find("AI绘画的优势和弊端不容忽视");
# 获取第一个实例
textFragment = fragments[0]
# 获取文本边界
bound = textFragment.Bounds[0]
# 创建一个文件链接注释
fileLinkAnnotation = PdfFileLinkAnnotation(bound, "/AI绘画的利弊及法律应对.docx")
# 将注释添加到文档的注释集合中
page.AnnotationsWidget.Add(fileLinkAnnotation)
# 保存修改后的文档
doc.SaveToFile("/文件链接注释.pdf")
doc.Dispose()

当您需要在 PDF 文档的某一个位置跳转到同一文件内另一个特定位置时,您可以尝试使用添加文档内链接注释。首先,通过 PdfTextFinder 类查找目标文本,然后实例化 PdfDocumentLinkAnnotation 对象,并设置其 Destination 属性,指定跳转目标位置,最后将其添加到 PDF 文档中。
from spire.pdf.common import *
from spire.pdf import *
# 创建一个 PdfDocument 类的对象
doc = PdfDocument()
# 加载 PDF 文档
doc.LoadFromFile("/示例文档.pdf")
# 获取文档中的一页
page = doc.Pages[0]
# 在该页上创建一个 PdfTextFinder 对象
finder = PdfTextFinder(page)
# 设置查找的选项
finder.Options.Parameter = TextFindParameter.WholeWord
# 查找指定文本的实例
fragments = finder.Find("AI绘画的优势和弊端不容忽视");
# 获取第一个实例
textFragment = fragments[0]
# 获取文本边界
bound = textFragment.Bounds[0]
# 创建一个文档内链接形式的注释
documentLinkAnnotation = PdfDocumentLinkAnnotation(bound)
# 设置注释的目标页面
documentLinkAnnotation.Destination = PdfDestination(doc.Pages[1]);
# 将注释添加到页面的注释集合中
page.AnnotationsWidget.Add(documentLinkAnnotation)
# 保存修改后的文档
doc.SaveToFile("/文档内链接注释.pdf")
doc.Dispose()

如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
Spire.DocViewer 8.9 已发布。本次更新升级了 .NET(.NET 4.6 和 4.8)和 .NET Core 平台的 HarfBuzzSharp 和 SkiaSharp。详情请阅读以下内容。
调整:
HarfBuzzSharp->8.3.0.1、SkiaSharp->3.116.1Spire.Office for Java 10.3.0 已发布。在该版本中,Spire.Doc for Java 支持设置默认的替换字体;Spire.XLS for Java 增强了 Excel 到 HTML 的转换;Spire.Presentation for Java 支持设置转换 PPT 到 PDF 所使用的线程数;Spire.PDF for Java 优化了转换 OFD 到 PDF 的耗时。此外,大量已知问题也在该版本中成功修复。详情请阅读以下内容。
获取 Spire.Office for Java 10.3.0,请点击:https://www.e-iceblue.cn/Downloads/Spire-Office-JAVA.html
新功能:
doc.setDefaultSubstitutionFontName("simsun");问题修复:
问题修复:
新功能:
presentation.getSaveToPdfOption().setThreadsCount(1); 优化:
问题修复: