我们很高兴地宣布 Spire.Office 10.2.0 正式发布。在该版本中, Spire.Doc 增加了大量用于自定义图表的 API;Spire.PDF 支持使用 PdfTextReplacer 类替换指定区域的文本;Spire.XLS 支持 MUNIT、FLOOR.PRECISE 和 CSC 等函数;Spire.Presentation 支持将幻灯片母版中的图像保存为 SVG。同时,还修复了大量已知错误。
版本信息如下:
- Spire.Doc.dll v13.2.3
- Spire.Pdf.dll v11.2.4
- Spire.XLS.dll v15.2.6
- Spire.Presentation.dll v10.2.1
- Spire.Barcode.dll v7.3.5
- Spire.Email.dll v6.6.0
- Spire.DocViewer.Forms.dll v8.8.3
- Spire.PdfViewer.Asp.dll v7.12.23
- Spire.PdfViewer.Forms.dll v7.12.23
- Spire.Spreadsheet.dll v7.5.2
- Spire.OfficeViewer.Forms.dll v8.7.15
- Spire.DataExport.dll v4.9.0
- Spire.DataExport.ResourceMgr.dll v2.1.0
https://www.e-iceblue.cn/Downloads/Spire-Office-NET.html
Spire.Doc
新功能:
- Chart 类新增了接口用于读写图表标题、数据标签、坐标轴、图例和数据表等格式。
- ChartTitle.Text 属性:用于设置图表标题文本。
- ChartDataLabel.ShowValue 属性:用于设置数据标签是否包含值。
- ChartAxis.CategoryType 属性:用于设置水平坐标轴类型(自动,文本或日期)。
- ChartLegend.Position 属性:用于设置图例位置。
- ChartDataTable.Show 属性:用于设置是否显示数据表。
- 命名空间变更:
- 优化了 Word 转 PDF 时的时间和资源占用,尤其是在处理大型文件或复杂布局时,内存使用效率更高。
Spire.Doc.Formatting.RowFormat.TablePositioning->Spire.Doc.Formatting.TablePositioning
Spire.Doc.Printing.PagesPreSheet->Spire.Doc.Printing.PagesPerSheet
Spire.XLS
新功能:
- 支持使用表格数据添加 Slicer 切片器。
- 支持使用透视表数据添加 Slicer 切片器。
- 支持移除 Slicer 切片器。
- 支持修改 Slicer 切片器。
- 支持获取 Slicer 切片器信息。
- 支持修改 Slicer 切片器的名称。
- 支持在使用 ExportDataTable() 时保留原有格式。
- 支持 MUNIT、FLOOR、PRECISE、CSC、IMCOSH、IMSINH 和 IMSECH 函数。
Workbook wb = new Workbook();
Worksheet worksheet = wb.Worksheets[0];
worksheet.Range["A1"].Value = "fruit";
worksheet.Range["A2"].Value = "grape";
worksheet.Range["A3"].Value = "blueberry";
worksheet.Range["A4"].Value = "kiwi";
worksheet.Range["A5"].Value = "cherry";
worksheet.Range["A6"].Value = "grape";
worksheet.Range["A7"].Value = "blueberry";
worksheet.Range["A8"].Value = "kiwi";
worksheet.Range["A9"].Value = "cherry";
worksheet.Range["B1"].Value = "year";
worksheet.Range["B2"].Value2 = 2020;
worksheet.Range["B3"].Value2 = 2020;
worksheet.Range["B4"].Value2 = 2020;
worksheet.Range["B5"].Value2 = 2020;
worksheet.Range["B6"].Value2 = 2021;
worksheet.Range["B7"].Value2 = 2021;
worksheet.Range["B8"].Value2 = 2021;
worksheet.Range["B9"].Value2 = 2021;
worksheet.Range["C1"].Value = "amount";
worksheet.Range["C2"].Value2 = 50;
worksheet.Range["C3"].Value2 = 60;
worksheet.Range["C4"].Value2 = 70;
worksheet.Range["C5"].Value2 = 80;
worksheet.Range["C6"].Value2 = 90;
worksheet.Range["C7"].Value2 = 100;
worksheet.Range["C8"].Value2 = 110;
worksheet.Range["C9"].Value2 = 120;
// Get slicer collection
XlsSlicerCollection slicers = worksheet.Slicers;
//Create a super table with the data from the specific cell range.
IListObject table = worksheet.ListObjects.Create("Super Table", worksheet.Range["A1:C9"]);
int count = 3;
int index = 0;
foreach (SlicerStyleType type in Enum.GetValues(typeof(SlicerStyleType)))
{
count += 5;
//Add a Slicer through 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[index];
xlsSlicer.Name = "slicers_" + count;
xlsSlicer.StyleType = type;
}
//Save to file
wb.SaveToFile("output.xlsx", ExcelVersion.Version2013);
Workbook wb = new Workbook();
Worksheet worksheet = wb.Worksheets[0];
worksheet.Range["A1"].Value = "fruit";
worksheet.Range["A2"].Value = "grape";
worksheet.Range["A3"].Value = "blueberry";
worksheet.Range["A4"].Value = "kiwi";
worksheet.Range["A5"].Value = "cherry";
worksheet.Range["A6"].Value = "grape";
worksheet.Range["A7"].Value = "blueberry";
worksheet.Range["A8"].Value = "kiwi";
worksheet.Range["A9"].Value = "cherry";
worksheet.Range["B1"].Value = "year";
worksheet.Range["B2"].Value2 = 2020;
worksheet.Range["B3"].Value2 = 2020;
worksheet.Range["B4"].Value2 = 2020;
worksheet.Range["B5"].Value2 = 2020;
worksheet.Range["B6"].Value2 = 2021;
worksheet.Range["B7"].Value2 = 2021;
worksheet.Range["B8"].Value2 = 2021;
worksheet.Range["B9"].Value2 = 2021;
worksheet.Range["C1"].Value = "amount";
worksheet.Range["C2"].Value2 = 50;
worksheet.Range["C3"].Value2 = 60;
worksheet.Range["C4"].Value2 = 70;
worksheet.Range["C5"].Value2 = 80;
worksheet.Range["C6"].Value2 = 90;
worksheet.Range["C7"].Value2 = 100;
worksheet.Range["C8"].Value2 = 110;
worksheet.Range["C9"].Value2 = 120;
// Get pivot table collection
Spire.Xls.Collections.PivotTablesCollection pivotTables = worksheet.PivotTables;
//Add a PivotTable to the worksheet
CellRange dataRange = worksheet.Range["A1:C9"];
PivotCache cache = wb.PivotCaches.Add(dataRange);
//Cell to put the pivot table
Spire.Xls.PivotTable pt = worksheet.PivotTables.Add("TestPivotTable", worksheet.Range["A12"], cache);
//Drag the fields to the row area.
PivotField pf = pt.PivotFields["fruit"] as PivotField;
pf.Axis = AxisTypes.Row;
PivotField pf2 = pt.PivotFields["year"] as PivotField;
pf2.Axis = AxisTypes.Column;
//Drag the field to the data area.
pt.DataFields.Add(pt.PivotFields["amount"], "SUM of Count", SubtotalTypes.Sum);
//Set PivotTable style
pt.BuiltInStyle = PivotBuiltInStyles.PivotStyleMedium10;
pt.CalculateData();
//Get slicer collection
XlsSlicerCollection slicers = worksheet.Slicers;
//Add a Slicer through pivot table data: here invoke Add(IPivotTable, string, int) api.
int index = slicers.Add(pt, "E12", 0);
XlsSlicer xlsSlicer = slicers[index];
xlsSlicer.Name = "test_xlsSlicer";
xlsSlicer.Width = 100;
xlsSlicer.Height = 120;
xlsSlicer.StyleType = SlicerStyleType.SlicerStyleLight2;
xlsSlicer.PositionLocked = true;
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache = xlsSlicer.SlicerCache;
slicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithNoData;
//Style setting
XlsSlicerCacheItemCollection slicerCacheItems = xlsSlicer.SlicerCache.SlicerCacheItems;
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems[0];
xlsSlicerCacheItem.Selected = false;
XlsSlicerCollection slicers_2 = worksheet.Slicers;
IPivotField r1 = pt.PivotFields["year"];
int index_2 = slicers_2.Add(pt, "I12", r1);
XlsSlicer xlsSlicer_2 = slicers[index_2];
xlsSlicer_2.RowHeight = 40;
xlsSlicer_2.StyleType = SlicerStyleType.SlicerStyleLight3;
xlsSlicer_2.PositionLocked = false;
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache_2 = xlsSlicer_2.SlicerCache;
slicerCache_2.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithDataAtTop;
//Style setting
XlsSlicerCacheItemCollection slicerCacheItems_2 = xlsSlicer_2.SlicerCache.SlicerCacheItems;
XlsSlicerCacheItem xlsSlicerCacheItem_2 = slicerCacheItems_2[1];
xlsSlicerCacheItem_2.Selected = 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 = wb.Worksheets[0];
XlsSlicerCollection slicers = worksheet.Slicers;
//Remove the first slicer by index
slicers.RemoveAt(0);
Worksheet worksheet_2 = wb.Worksheets[1];
//Remove all slicers
worksheet_2.Slicers.Clear();
wb.SaveToFile(outputFile, ExcelVersion.Version2013);
Workbook wb = new Workbook();
wb.LoadFromFile("in.xlsx");
//Get the first worksheet of workbook
Worksheet worksheet = wb.Worksheets[0];
//Get slicer collection
XlsSlicerCollection slicers = worksheet.Slicers;
//Style setting
XlsSlicer xlsSlicer = slicers[0];
xlsSlicer.StyleType = SlicerStyleType.SlicerStyleDark4;
xlsSlicer.Caption = "Slicer";
xlsSlicer.PositionLocked = true;
XlsSlicerCacheItemCollection slicerCacheItems = xlsSlicer.SlicerCache.SlicerCacheItems;
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems[0];
xlsSlicerCacheItem.Selected = false;
string displayValue = xlsSlicerCacheItem.DisplayValue;
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache = xlsSlicer.SlicerCache;
slicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithNoData;
//Save to file
wb.SaveToFile("out.xlsx", ExcelVersion.Version2013);
Workbook wb = new Workbook();
wb.LoadFromFile("in.xlsx");
//Get slicer collection of first worksheet
Worksheet worksheet = wb.Worksheets[0];
XlsSlicerCollection slicers = worksheet.Slicers;
StringBuilder builder = new StringBuilder();
builder.AppendLine("slicers.Count:" + slicers.Count);
XlsSlicer xlsSlicer = slicers[1];
builder.AppendLine("xlsSlicer.Name:" + xlsSlicer.Name);
builder.AppendLine("xlsSlicer.Caption:" + xlsSlicer.Caption);
builder.AppendLine("xlsSlicer.NumberOfColumns:" + xlsSlicer.NumberOfColumns);
builder.AppendLine("xlsSlicer.ColumnWidth:" + xlsSlicer.ColumnWidth);
builder.AppendLine("xlsSlicer.RowHeight:" + xlsSlicer.RowHeight);
builder.AppendLine("xlsSlicer.ShowCaption:" + xlsSlicer.ShowCaption);
builder.AppendLine("xlsSlicer.PositionLocked:" + xlsSlicer.PositionLocked);
builder.AppendLine("xlsSlicer.Width:" + xlsSlicer.Width);
builder.AppendLine("xlsSlicer.Height:" + xlsSlicer.Height);
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache = xlsSlicer.SlicerCache;
builder.AppendLine("slicerCache.SourceName:" + slicerCache.SourceName);
builder.AppendLine("slicerCache.IsTabular:" + slicerCache.IsTabular);
builder.AppendLine("slicerCache.Name:" + slicerCache.Name);
XlsSlicerCacheItemCollection slicerCacheItems = slicerCache.SlicerCacheItems;
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems[1];
builder.AppendLine("xlsSlicerCacheItem.Selected:" + xlsSlicerCacheItem.Selected);
File.WriteAllText("out.txt", builder.ToString());
wb.Dispose();
Workbook wb = new Workbook();
wb.LoadFromFile(inputFile);
Worksheet worksheet = wb.Worksheets[0];
XlsSlicerCollection slicers = worksheet.Slicers;
XlsSlicer xlsSlicer = slicers[0];
xlsSlicer.Caption = "Name1";
wb.SaveToFile(outputFile, ExcelVersion.Version2013);
ExportTableOptions op = new ExportTableOptions();
op.ExportColumnNames = true;
op.KeepDataType = true;
var r = sheet.Range["A1:M7"];
Workbook workbook = new Workbook();
workbook.Worksheets[0].Range["C2"].Formula = "=MUNIT(5)";
workbook.Worksheets[0].Range["C8"].Formula = "=MUNIT(0)";
workbook.Worksheets[0].Range["A1"].Formula = "=FLOOR.PRECISE(3.2)";
workbook.Worksheets[0].Range["D1"].Formula = "CSC(-2)";
workbook.Worksheets[0].Range["A3"].Formula = "=IMCSCH(\"4 + 3i\")";
workbook.CalculateAllValue();
问题修复:
- 修复了语言区域设置为“匈牙利”时,文档打开报错的问题。
- 修复了更新透视表后,日语字符变成了英文字符的问题。
- 修复了 sheet 转图片后,日期格式不一致的问题。
- 修复了设置 sheet 标签颜色为 Color.Empty,结果为黑色的问题。
- 修复了德语模式 formula 生成后效果不正确的问题。
- 修复了保存 shape 到图片, 程序抛 NullReferenceException 的问题。
- 修复了 Excel 转 PDF,切片器丢失的问题。
Spire.Presentation
新功能:
- 支持保存母版中的图片为 SVG。
Presentation ppt = new Presentation();
ppt.LoadFromFile(inputFile);
int num = 1;
IMasterSlide masterSlide = ppt.Masters[0];
for (int i = 0; i < masterSlide.Shapes.Count; i++)
{
IShape s = masterSlide.Shapes[i];
if (s is SlidePicture)
{
SlidePicture ps = s as SlidePicture;
byte[] svgByte = s.SaveAsSvgInSlide();
FileStream fs = new FileStream(outputFile +num + ".svg", FileMode.Create);
fs.Write(svgByte, 0, svgByte.Length);
fs.Close();
num++;
}
}
问题修复:
- 修复了设置 TextAutofitType.Shape 不生效的问题。
- 修复了使用 Shapes.AppendShapeConnector 效果不正确的问题。
- 修复了获取不到 PPT 文档 shape 和 image 的链接的问题。
- 修复了转 shape 到 svg,报 InvalidCastException 的问题。
- 修复了加载 PPTX 文档,程序抛 "Property not found" 的问题。
Spire.PDF 11.2.4
新功能:
- PdfTextReplacer支持指定区域替换。
- 支持获取 Action 链接的书签信息。
- 支持返回 PdfTextReplacer.ReplaceAllText 替换的个数。
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile(inputFile);
for (int i = 0; i < pdf.Pages.Count; i++)
{
PdfPageBase page = pdf.Pages[i] ;
PdfTextReplacer replacer = new PdfTextReplacer(page);
PdfTextReplaceOptions replaceOptions = new PdfTextReplaceOptions();
RectangleF rectangle = new RectangleF(10, 0, 841, 150);
replaceOptions.SetReplacementArea(rectangle);
replaceOptions.ReplaceType = PdfTextReplaceOptions.ReplaceActionType.IgnoreCase;
replacer.Options = replaceOptions;
replacer.ReplaceAllText("sql", "123456");
}
pdf.SaveToFile(outputFile);
pdf.Dispose();
PdfDocument doc = new PdfDocument();
doc.LoadFromFile(inputFile);
PdfFormWidget formWidget = (PdfFormWidget)doc.Form;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("btnAction:");
for (int i = 0; i < formWidget.FieldsWidget.Count; ++i)
{
var field = formWidget.FieldsWidget[i] as PdfButtonWidgetFieldWidget;
if (field.Actions.MouseUp != null && field.Actions.MouseUp is PdfNamedAction)
{
var aaa = (PdfNamedAction)field.Actions.MouseUp;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseUp-" + aaa.Destination.ToString());
}
else if (field.Actions.MouseDown != null && field.Actions.MouseDown is PdfNamedAction)
{
var aaa = (PdfNamedAction)field.Actions.MouseDown;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseDown--" + aaa.Destination.ToString());
}
else if (field.Actions.MouseDown != null && field.Actions.MouseDown is PdfUriAction)
{
var aaa = (PdfUriAction)field.Actions.MouseDown;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseDown--" + aaa.Uri.ToString());
}
else if (field.Actions.MouseUp != null && field.Actions.MouseUp is PdfUriAction)
{
var aaa = (PdfUriAction)field.Actions.MouseUp;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseUp-" + aaa.Uri.ToString());
}
else if (field.Actions.MouseDown != null && field.Actions.MouseDown is PdfGotoNameAction)
{
var aaa = (PdfGotoNameAction)field.Actions.MouseDown;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseDown-" + aaa.Destination.ToString());
}
}
File.WriteAllText(outputFile, stringBuilder.ToString());
doc.Dispose();
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile(inputFile);
PdfPageBase page = pdf.Pages[0];
PdfTextReplacer replacer = new PdfTextReplacer(page);
int count = replacer.ReplaceAllText("SQL", "ABC");
问题修复:
- 优化了 PdfCompressor 压缩 PDF 功能。
- 修复了打印 PDF 效果不正确的问题。
- 修复了 PdfTextBoxField 中多行文本展示效果不正确的问题。
- 修复了 PDF 转图片效果不正确的问题。
- 修复了 PDF 转 HTML 字符重叠的问题。
- 修复了合并文档抛异常 "System.NullReferenceException" 的问题。