We’re pleased to announce the release of Spire.Office 11.3.0. In this version, supports converting Word to Excel and adding and manipulating SmartArt; Spire.XLS supports manipulating the VBA Macro Project; Spire.PDFViewer supports .NET 6.0 WPF and WinForms applications. Moreover, a large number of known bugs has been fixed successfully in this version.
In this version, the most recent versions of Spire.Doc, Spire.PDF, Spire.XLS, Spire.Presentation, Spire.Barcode, Spire.DocViewer, Spire.PDFViewer, Spire.Email, Spire.Spreadsheet, and Spire.OfficeViewer are included.
DLL Versions:
- Spire.Doc.dll v14.3.5
- Spire.Pdf.dll v12.3.7
- Spire.XLS.dll v16.3.6
- Spire.Presentation.dll v11.3.1
- Spire.Barcode.dll v7.5.0
- Spire.Email.dll v6.8.0
- Spire.DocViewer.Forms.dll v8.9.5
- Spire.PdfViewer.Asp.dll v8.2.13
- Spire.PdfViewer.Forms.dll v8.2.13
- Spire.Spreadsheet.dll v7.5.3
- Spire.OfficeViewer.Forms.dll v8.8.1
Here is a list of changes made in this release
Spre.doc
| Category | ID | Description |
| New Feature | SPIREDOC-9870 | Added support for the "Automatically adjust right indent when defining grid" feature.
paragraph.Format.AdjustRightIndent = true; // Default value is true |
| New Feature | SPIREDOC-11030 | Added support for the "Kerning for fonts" feature.
textRange.CharacterFormat.Kerning = 2.5f; |
| New Feature | SPIREDOC-10514 SPIREDOC-11494 | Added several new interfaces for adding and manipulating SmartArt graphics.
Document document = new Document();
Section section = document.AddSection();
Spire.Doc.Documents.Paragraph paragraph = section.AddParagraph(); paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center;
Spire.Doc.Fields.TextRange textRange = paragraph.AppendText("RepeatingBendingProcess");
textRange.CharacterFormat.FontSize = 28f;
textRange.CharacterFormat.FontName = "Times New Roman";
paragraph = section.AddParagraph();
paragraph = section.AddParagraph();
paragraph.Format.HorizontalAlignment = HorizontalAlignment.Center;
// Add SmartArt with "Segmented Process" layout
Spire.Doc.Fields.Shapes.Shape shape = paragraph.AppendSmartArt(SmartArtType.RepeatingBendingProcess, 432, 252);
SmartArt repeatingBendingSmartArt = shape.SmartArt;
// Add node text
SmartArtNode process1 = repeatingBendingSmartArt.Nodes[0];
process1.Text = "1";
((Spire.Doc.Fields.TextRange)process1.Paragraphs[0].ChildObjects[0]).CharacterFormat.FontName = "Calibri";
((Spire.Doc.Fields.TextRange)process1.Paragraphs[0].ChildObjects[0]).CharacterFormat.FontSize = 20f;
((Spire.Doc.Fields.TextRange)process1.Paragraphs[0].ChildObjects[0]).CharacterFormat.TextColor = Color.Crimson;
// Add node text
SmartArtNode process2 = repeatingBendingSmartArt.Nodes[1];
process2.Text = "2";
((Spire.Doc.Fields.TextRange)process2.Paragraphs[0].ChildObjects[0]).CharacterFormat.FontSize = 15f;
// Add node text
SmartArtNode process3 = repeatingBendingSmartArt.Nodes[2];
process3.Text = "3";
((Spire.Doc.Fields.TextRange)process3.Paragraphs[0].ChildObjects[0]).CharacterFormat.FontSize = 10f;
// Add node text
SmartArtNode process4 = repeatingBendingSmartArt.Nodes[3];
process4.Text = "4";
((Spire.Doc.Fields.TextRange)process4.Paragraphs[0].ChildObjects[0]).CharacterFormat.FontSize = 10f;
// Add node text
SmartArtNode process5 = repeatingBendingSmartArt.Nodes[4];
process5.Text = "5";
((Spire.Doc.Fields.TextRange)process5.Paragraphs[0].ChildObjects[0]).CharacterFormat.FontSize = 10f;
document.SaveToFile(outputFile, FileFormat.Docx);
document.Close();
|
| New Feature | SPIREDOC-11622 | Added support for retrieving text from all nodes in SmartArt.
using (Document document = new Document(inputFile))
{
// Iterate through all sections
foreach (Section section in document.Sections)
{
if (section?.Paragraphs == null) continue;
// Iterate through all paragraphs in the section
foreach (Spire.Doc.Documents.Paragraph paragraph in section.Paragraphs)
{
foreach (var childObj in paragraph.ChildObjects)
{
if (childObj is Spire.Doc.Fields.Shapes.Shape shape && shape.HasSmartArt)
{
SmartArt smartArt = shape.SmartArt;
if (smartArt == null) continue;
TraverseSmartArtNodes(smartArt.Nodes, builder, 0);
}
}
}
}
}
public static void TraverseSmartArtNodes(SmartArtNodeCollection nodes, StringBuilder builder, int level)
{
if (nodes == null || nodes.Count == 0) return;
for (int nodeIdx = 0; nodeIdx < nodes.Count; nodeIdx++)
{
SmartArtNode node = nodes[nodeIdx];
if (node == null) continue;
// Clean node text
string nodeText = node.Text != null ? node.Text.Trim() : "Empty Text";
if (nodeText == "\r" || string.IsNullOrEmpty(nodeText)) continue;
// Concatenate node level identifier
string nodePrefix;
switch (level)
{
case 0:
nodePrefix = "smartArt.Nodes";
break;
case 1:
nodePrefix = "smartArt.Nodes.ChildNodes";
break;
case 2:
nodePrefix = "smartArt.Nodes.ChildNodes.ChildNodes";
break;
default:
nodePrefix = $"smartArt.Nodes.Level{level}";
break;
}
// Basic text output
builder.AppendLine($"{nodePrefix}_{nodeIdx}: {nodeText}");
// Recursively process child nodes
TraverseSmartArtNodes(node.ChildNodes, builder, level + 1);
}
}
|
| New Feature | - | Added support for Word to Excel conversion.
Document.SaveToFile("output.xlsx", FileFormat.XLSX);
|
| Adjustment | - | Moved HtmlExportOptions from Spire.Doc to Spire.Doc.Exporting. |
| Adjustment | - | Moved MarkdownExportOptions from Spire.Doc to Spire.Doc.Exporting. |
| Bug Fix | SPIREDOC-11724 | Fixed the issue where paragraph text was retrieved incorrectly. |
| Bug Fix | SPIREDOC-11743 | Fixed the issue where Arabic text fonts were altered when converting Word to PDF. |
| Bug Fix | SPIREDOC-11787 | Fixed the issue where extra blank pages appeared during page extraction. |
Spre.XLS
| Category | ID | Description |
| New Feature | SPIREXLS-938 SPIREXLS-5995 | Added support for VBA Macro Project manipulation, covering creation, reading, modification, and deletion.
Adding VBA project: Workbook workbook = new Workbook();
// Add VBA project to the document
IVbaProject vbaProject = workbook.VbaProject;
vbaProject.Name = "SampleVBAMacro";
string text = "Encoding before modification: " + vbaProject.CodePage.ToString() + "\n";
vbaProject.CodePage = 936; // Set encoding, support Chinese
text += "Encoding after modification: " + vbaProject.CodePage.ToString() + "\n";
File.WriteAllText(outputFile_TXT, text);
// Add VBA module to the project
IVbaModule vbaModule = vbaProject.Modules.Add("SampleModule", VbaModuleType.Module);
// Set VBA macro source code
vbaModule.SourceCode = @"
Sub ExampleMacro()
' Declare variables
Dim ws As Worksheet
Dim i As Integer
' Set reference to the active worksheet
Set ws = ActiveSheet
' Clear worksheet content (optional)
ws.Cells.Clear
' Populate sample data
With ws
' Write header row
.Range(""A1:C1"").Value = Array(""No."", ""Project Name"", ""Amount"")
' Loop to fill 10 rows of data
For i = 1 To 10
.Cells(i + 1, 1).Value = i ' No. column
.Cells(i + 1, 2).Value = ""Project "" & i ' Project Name column
.Cells(i + 1, 3).Value = i * 100 ' Amount column (example calculation)
Next i
' AutoFit column widths
.Columns(""A:C"").AutoFit
' Format header row
With .Range(""A1:C1"")
.Font.Bold = True
.Interior.Color = RGB(200, 220, 255) ' Light blue background
End With
' Format amount column
.Range(""C2:C11"").NumberFormat = ""$#,##0.00""
End With
' Show completion message
MsgBox ""Data population completed!"", vbInformation, ""Operation Prompt""
End Sub";
// Save the Excel file
workbook.SaveToFile(outputFile_Xls, FileFormat.Version97to2003);
Reading VBA project: Workbook wb = new Workbook(); wb.LoadFromFile(inputFile); Worksheet ws = wb.Worksheets[0]; IVbaProject vbaProject = wb.VbaProject; string text = "IsProtected:" + vbaProject.IsProtected + "\n"; text += "Name:" + vbaProject.Name + "\n"; text += "Description:" + vbaProject.Description + "\n"; text += "HelpFileName:" + vbaProject.HelpFileName + "\n"; text += "ConditionalCompilation:" + vbaProject.ConditionalCompilation + "\n"; text += "LockProjectView:" + vbaProject.LockProjectView + "\n"; text += "Password:" + vbaProject.Password + "\n"; text += "CodePage:" + vbaProject.CodePage + "\n"; IVbaModule mod = vbaProject.Modules.GetWorksheetModule(ws); text += "IVbaModule:" + "\n"; text += "Name:" + mod.Name.ToString() + "\n"; text += "SourceCode:\n" + mod.SourceCode.ToString() + "\n"; text += "Type:" + mod.Type.ToString() + "\n"; File.WriteAllText(outputFile_TXT, text.ToString()); vbaProject.Modules.Clear(); wb.SaveToFile(outputFile); Editing VBA project: Workbook wb = new Workbook(); wb.LoadFromFile(inputFile); Worksheet ws = wb.Worksheets[0]; IVbaProject vbaProject = wb.VbaProject; vbaProject.Password = "1234"; vbaProject.Name = "modify"; vbaProject.Description = "Description"; vbaProject.HelpFileName = "image1.png"; vbaProject.ConditionalCompilation = "DEBUG = 2"; vbaProject.LockProjectView = true; IVbaModule mod = vbaProject.Modules.GetWorksheetModule(ws); mod.Name = "IVbaModule"; mod.SourceCode = "Dim lRow As Long"; mod.Type = VbaModuleType.Module; wb.SaveToFile(outputFile); Removing VBA project: Workbook wb1 = new Workbook();
wb1.LoadFromFile(inputFile_1);
IVbaProject vbaProject1 = wb1.VbaProject;
vbaProject1.Modules.Remove("SampleModule");
vbaProject1.Modules.RemoveAt(0);
wb1.SaveToFile(outputFile_1);
|
| New Feature | SPIREXLS-6020 | Added support for Data Simulation Analysis (Scenario Manager), covering creation, editing, deletion, summary generation, and merging.
Creating scenarios: Workbook wb = new Workbook();
wb.LoadFromFile(inputFile);
Worksheet worksheet = wb.Worksheets[0];
// Access the collection of scenarios in the worksheet
XlsScenarioCollection scenarios = worksheet.Scenarios;
// Initialize list objects with different values for scenarios
List<object> currentChangePercentage_Values = new List<object> { 0.23, 0.8, 1.1, 0.5, 0.35, 0.2 };
List<object> increasedChangePercentage_Values = new List<object> { 0.45, 0.56, 0.9, 0.5, 0.58, 0.43 };
List<object> decreasedChangePercentage_Values = new List<object> { 0.3, 0.2, 0.5, 0.3, 0.5, 0.23 };
List<object> currentQuantity_Values = new List<object> { 1500, 3000, 5000, 4000, 500, 4000 };
List<object> increasedQuantity_Values = new List<object> { 1000, 5000, 4500, 3900, 10000, 8900 };
List<object> decreasedQuantity_Values = new List<object> { 1000, 2000, 3000, 3000, 300, 4000 };
// Add scenarios in the worksheet with different values for the same cells
scenarios.Add("Current % of Change", worksheet.Range["F5:F10"], currentChangePercentage_Values);
scenarios.Add("Increased % of Change", worksheet.Range["F5:F10"], increasedChangePercentage_Values);
scenarios.Add("Decreased % of Change", worksheet.Range["F5:F10"], decreasedChangePercentage_Values);
scenarios.Add("Current Quantity", worksheet.Range["D5:D10"], currentQuantity_Values);
scenarios.Add("Increased Quantity", worksheet.Range["D5:D10"], increasedQuantity_Values);
scenarios.Add("Decreased Quantity", worksheet.Range["D5:D10"], decreasedQuantity_Values);
// Saving the workbook
wb.SaveToFile(outputFile, ExcelVersion.Version2013);
wb.Dispose();
Generating scenario summary: Workbook wb = new Workbook();
wb.LoadFromFile(inputFile);
Worksheet worksheet = wb.Worksheets[0];
// Access the collection of scenarios in the worksheet
XlsScenarioCollection scenarios = worksheet.Scenarios;
// Initialize list objects with different values for scenarios
List<object> currentChangePercentage_Values = new List<object>{ 0.23, 0.8, 1.1, 0.5, 0.35, 0.2 };
List<object> increasedChangePercentage_Values = new List<object> { 0.45, 0.56, 0.9, 0.5, 0.58, 0.43 };
List<object> decreasedChangePercentage_Values = new List<object> { 0.3, 0.2, 0.5, 0.3, 0.5, 0.23 };
List<object> currentQuantity_Values = new List<object> { 1500, 3000, 5000, 4000, 500, 4000 };
List<object> increasedQuantity_Values = new List<object> { 1000, 5000, 4500, 3900, 10000, 8900 };
List<object> decreasedQuantity_Values = new List<object> { 1000, 2000, 3000, 3000, 300, 4000 };
// Add scenarios in the worksheet with different values for the same cells
scenarios.Add("Current % of Change", worksheet.Range["F5:F10"], currentChangePercentage_Values);
scenarios.Add("Increased % of Change", worksheet.Range["F5:F10"], increasedChangePercentage_Values);
scenarios.Add("Decreased % of Change", worksheet.Range["F5:F10"], decreasedChangePercentage_Values);
scenarios.Add("Current Quantity", worksheet.Range["D5:D10"], currentQuantity_Values);
scenarios.Add("Increased Quantity", worksheet.Range["D5:D10"], increasedQuantity_Values);
scenarios.Add("Decreased Quantity", worksheet.Range["D5:D10"], decreasedQuantity_Values);
// Create Summary
worksheet.Scenarios.Summary(worksheet.Range["L7"]);
// Saving the workbook
wb.SaveToFile(outputFile, ExcelVersion.Version2013);
wb.Dispose();
Editing scenario: Workbook wb = new Workbook(); wb.LoadFromFile(inputFile); Worksheet worksheet = wb.Worksheets[0]; // Access the collection of scenarios in the worksheet XlsScenarioCollection scenarios = worksheet.Scenarios; XlsScenario scenario1 = scenarios[0]; XlsScenario scenario2 = scenarios[1]; // Modify the scenario scenario1.SetVariableCells(worksheet.Range["A1:A5"], scenario2.Values); CellRange sourceCell = worksheet.Range["B1:B5"]; scenario2.SetVariableCells(sourceCell, scenario2.Values); scenario1.Show(); scenario2.Show(); // Saving the workbook wb.SaveToFile(outputFile, ExcelVersion.Version2013); wb.Dispose(); Merging scenario: Workbook wb = new Workbook(); wb.LoadFromFile(inputFile); Worksheet worksheet1 = wb.Worksheets[0]; Worksheet worksheet2 = wb.Worksheets[1]; // Merge the scenario worksheet1.Scenarios.Merge(worksheet2); // Saving the workbook wb.SaveToFile(outputFile, ExcelVersion.Version2013); wb.Dispose(); Deleting scenario: Workbook wb = new Workbook();
wb.LoadFromFile(inputFile);
Worksheet worksheet = wb.Worksheets[0];
// Access the collection of scenarios in the worksheet
XlsScenarioCollection scenarios = worksheet.Scenarios;
// delete the scenario
scenarios.RemoveScenarioAt(0);
scenarios.RemoveScenarioByName("two");
string content = "";
content += "Count:" + scenarios.Count + "\n";
content += "ContainsScenario:" + scenarios.ContainsScenario("two").ToString() + "\n";
content += "ContainsScenario:" + scenarios.ContainsScenario("one").ToString() + "\n";
File.WriteAllText(outputFile, content.ToString());
// Saving the workbook
wb.SaveToFile(outputFile, ExcelVersion.Version2013);
wb.Dispose();
|
| Bug Fix | SPIREXLS-5995 SPIREXLS-6077 | Fixed the issue where macros were lost when copying worksheets. |
Spire.Presentation
| Category | ID | Description |
| Bug Fix | SPIREPPT-2728 | Fixes the issue where shape shadow effects could not be retrieved. |
| Bug Fix | SPIREPPT-3072 | Fixes the issue where text offset occurred when converting PowerPoint to PDF. |
| Bug Fix | SPIREPPT-3081 | Fixes the issue where the application threw a "Property not found" exception when loading a PowerPoint containing 3D animations. |
| Bug Fix | SPIREPPT-3085 | Fixes the issue where the application threw an "Object reference not set to an instance of an object" exception when converting PowerPoint to PDF. |
Spire.PDF
| Category | ID | Description |
| Bug Fix | SPIREPDF-5696 SPIREPDF-6453 | Fixed an issue where merging PDFs threw a System.OutOfMemoryException. |
| Bug Fix | SPIREPDF-7070 | Fixed an issue where merged PDF documents could not be opened in web browsers. |
| Bug Fix | SPIREPDF-7938 | Fixed an issue where checkmark symbols in checkboxes were missing after converting PDF to PDF/A-1a and other standard formats. |
| Bug Fix | SPIREPDF-7957 | Fixed an issue where content formatting was incorrect when converting PDF to Word. |
| Bug Fix | SPIREPDF-7965 | Fixed an issue where converting PDF to images threw a System.NullReferenceException. |
| Bug Fix | SPIREPDF-7966 | Fixed an issue where loading PDF threw an "An item with the same key has already been added" exception. |
| Bug Fix | SPIREPDF-7969 | Fixed an issue where finding text within a specified area returned incorrect results. |
Spire.PDFViewer
| Category | ID | Description |
| New Feature | - | Added support for .NET 6.0 WPF and WinForms applications. |