Spire.Office for .NET 10.2.0 is released

Spire.Office for .NET 10.2.0 is released

2025-02-28 09:44:47

We are excited to announce the release of Spire.Office 10.2.0. In this version, Spire.Doc adds numerous APIs for customizing charts; Spire.PDF supports to replace text in the specified area using the PdfTextReplacer class; Spire.XLS supports functions such as MUNIT, FLOOR.PRECISE, and CSC; Spire.Presentation supports to save images in the master slide as SVG. Meanwhile, a large number of known bugs have been fixed.

In this version, the most recent versions of the DLLs are included.

DLL Versions:

  • 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
Click the link to get the version Spire.Office 10.2.0:
More information of Spire.Office new release or hotfix:

Here is a list of changes made in this release

Spire.Doc 13.2.3

Category ID Description
New feature - Adds new interfaces for reading and writing chart titles, chart data labels, chart axis, chart legends, chart data tables and other attributes.
  • ChartTitle.Text property: Sets the chart title text.
  • ChartDataLabel.ShowValue property: Sets whether the data label includes the value.
  • ChartAxis.CategoryType property: Sets the type of the horizontal axis (automatic, text, or date).
  • ChartLegend.Position property: Sets the position of the legend.
  • ChartDataTable.Show property: Sets whether to display the data table.
New feature - Namespace changes:
Spire.Doc.Formatting.RowFormat.TablePositioning->Spire.Doc.Formatting.TablePositioning
Spire.Doc.Printing.PagesPreSheet->Spire.Doc.Printing.PagesPerSheet    
New feature - Optimizes the time and resource consumption when converting Word to PDF, especially when working with large files or complex layouts.

Spire.XLS

Category ID Description
New feature - Added support for creating slicer using table data.
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);
New feature - Added support for creating slicer using pivot table data.
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);
New feature - Added support for removing slicer.
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);
New feature - Added support for modifying slicer.
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);
New feature - Added support for retrieving slicer information.
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();
New feature SPIREXLS-5302 Added support for modifying the names of slicer.
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);
New feature SPIREXLS-568 Supports preserving the original format in the ExportDataTable() function.
ExportTableOptions op = new ExportTableOptions();
op.ExportColumnNames = true;
op.KeepDataType = true;
var r = sheet.Range["A1:M7"]; 
New feature SPIREXLS-5539 Supports the MUNIT function.
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();
New feature SPIREXLS-5540 Supports the FLOOR function.
New feature SPIREXLS-5541 Supports the PRECISE function.
New feature SPIREXLS-5681 Supports the CSC function.
New feature SPIREXLS-5682 Supports the IMCOSH function.
New feature SPIREXLS-5683 Supports the IMSINH function.
New feature SPIREXLS-5684 Supports the IMSECH function.
Bug SPIREXLS-5674 Fixes the issue that document opening errors occurred when setting the language region to "Hungarian".
Bug SPIREXLS-5675 Fixes the issue that Japanese characters were converted to English characters after updating the pivot table.
Bug SPIREXLS-5680 Fixes the issue that the date format was inconsistent after converting a sheet to an image.
Bug SPIREXLS-5686 Fixes the issue that black color was resulted when setting the sheet tab color to Color.Empty.
Bug SPIREXLS-5692 Fixes the issue that the formula generated in German mode was incorrect.
Bug SPIREXLS-5708 Fixes the issue that saving a shape to an image caused a NullReferenceException.
Bug SPIREXLS-1922
SPIREXLS-5641
Fixed the issue of missing slicers when converting Excel to PDF.

Spire.Presentation

Category ID Description
New feature SPIREPPT-2724 Supports saving images in master slides as 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++;
	}                
}
Bug SPIREPPT-2626 Fixes the issue that setting TextAutofitType.Shape did not take effect.
Bug SPIREPPT-2627 Fixes the issue that the effect of using Shapes.AppendShapeConnector was not correct.
Bug SPIREPPT-2706 Fixes the issue that the links of shapes and images in PowerPoint documents could not be obtained.
Bug SPIREPPT-2723 Fixes the issue that the program threw InvalidCastException when converting shapes to SVG.
Bug SPIREPPT-2726 Fixes the issue that the program threw "Property not found" when loading a PPTX document.

Spire.PDF

Category ID Description
New feature SPIREPDF-7255 Supports replacing text in specific areas using PdfTextReplacer.
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();
New feature SPIREPDF-7292 Supports retrieving bookmark information from Action links.
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();
New feature SPIREPDF-7345 Supports returning the count of replacements made by PdfTextReplacer.ReplaceAllText.
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile(inputFile);
PdfPageBase page = pdf.Pages[0];
PdfTextReplacer replacer = new PdfTextReplacer(page);
int count = replacer.ReplaceAllText("SQL", "ABC");
Bug SPIREPDF-6551 Optimizes the PDF compression function of PdfCompressor.
Bug SPIREPDF-7061
SPIREPDF-7082
Fixes the issue that the PDF printing effect was incorrect.
Bug SPIREPDF-7313 Fixes the issue that the display effect of multi-line text in PdfTextBoxField was incorrect.
Bug SPIREPDF-7320 Fixes the issue that the PDF-to-image conversion effect was incorrect.
Bug SPIREPDF-7325 Fixes the issue that characters overlapped after converting PDF to HTML.
Bug SPIREPDF-7342 Fixes the issue that the exception “System.NullReferenceException” was thrown when merging documents.