Knowledgebase (2609)
Children categories
When creating flowcharts, relationship diagrams, or data annotations, inserting lines into an Excel worksheet is a common requirement. Spire.XLS for JavaScript provides rich line APIs for creating various line types (straight lines, curved lines, elbow connectors, etc.) and arrow-tipped connectors. All operations are performed directly in the browser based on WebAssembly, with no backend service required.
This article covers two core features:
For installation and project configuration, refer to Integrating Spire.XLS for JavaScript in a React Project. The examples below assume Spire.XLS is installed and the WebAssembly module is initialized.
Insert Different Types of Lines
The sheet.Lines.AddLine() method inserts line shapes at a specified position. Using the LineShapeType enum, you can create various line types: straight lines (Line), curved lines (CurveLine), elbow connectors (ElbowLine), and inverted lines (LineInv). The appearance of lines can be customized through properties such as DashStyle (dash style), Color (color), and Weight (thickness).
The main steps are as follows:
- Create a
Workbookobject and get the first worksheet. - Call the
Worksheet.Lines.AddLine()method, passing position parameters andLineShapeTypeto specify the line type. - Customize line appearance through the
DashStyle,Color,Weight, andEndArrowHeadStyleproperties. - Save the workbook with the
Workbook.SaveToFile()method.
Here is a complete code example showing how to insert four different types of lines into Excel in React:
function App() {
const addLineShapes = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
// Check whether the module is ready
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// Load the font into the VFS for text measurement and column auto-fit
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
// Create a new workbook and get the first worksheet
const workbook = new xlsModule.Workbook();
const sheet = workbook.Worksheets.get(0);
// Add a straight line - solid, CadetBlue, weight 2, with arrow
let line1 = sheet.Lines.AddLine({ row: 10, column: 2, width: 200, height: 1, lineShapeType: xlsModule.LineShapeType.Line });
line1.DashStyle = xlsModule.ShapeDashLineStyleType.Solid;
line1.Color = xlsModule.Color.get_CadetBlue();
line1.Weight = 2;
line1.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
// Add a curved line - dotted, OrangeRed, weight 2
let line2 = sheet.Lines.AddLine({ row: 12, column: 2, width: 200, height: 1, lineShapeType: xlsModule.LineShapeType.CurveLine });
line2.DashStyle = xlsModule.ShapeDashLineStyleType.Dotted;
line2.Color = xlsModule.Color.get_OrangeRed();
line2.Weight = 2;
// Add an elbow connector - DashDotDot, Purple, weight 2
let line3 = sheet.Lines.AddLine({ row: 14, column: 2, width: 200, height: 1, lineShapeType: xlsModule.LineShapeType.ElbowLine });
line3.DashStyle = xlsModule.ShapeDashLineStyleType.DashDotDot;
line3.Color = xlsModule.Color.get_Purple();
line3.Weight = 2;
// Add an inverted line - Dashed, Green, weight 2
let line4 = sheet.Lines.AddLine({ row: 16, column: 2, width: 200, height: 1, lineShapeType: xlsModule.LineShapeType.LineInv });
line4.DashStyle = xlsModule.ShapeDashLineStyleType.Dashed;
line4.Color = xlsModule.Color.get_Green();
line4.Weight = 2;
// Save the workbook
const outputFileName = 'AddLineShapes.xlsx';
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
// Release resources
workbook.Dispose();
// Read the saved file from the VFS and trigger the download
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Add Line Shapes</h1>
<button onClick={addLineShapes}>Start</button>
</div>
);
}
export default App;
Effect of inserting different line types:

Insert Arrow-Tipped Lines
The sheet.TypedLines.AddLine() method inserts arrow-tipped lines. Unlike Lines.AddLine(), TypedLines supports precise positioning using pixel coordinates or row/column coordinates, and supports setting different arrow head styles on both ends (beginning BeginArrowHeadStyle and end EndArrowHeadStyle).
The main steps are as follows:
- Create a
Workbookobject and get the first worksheet. - Call the
Worksheet.TypedLines.AddLine()method to create a line. - Set line position through the
Top,Left,Width, andHeightproperties (in pixels). - Set arrow styles on both ends through
BeginArrowHeadStyleandEndArrowHeadStyle. - Specify the line type through
LineShapeType(straight, elbow, curved, etc.). - Save the workbook with the
Workbook.SaveToFile()method.
Here is a complete code example showing how to insert six different types of arrow lines into Excel in React:
function App() {
const addArrowLines = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
// Check whether the module is ready
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// Load the font into the VFS for text measurement and column auto-fit
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
// Create a new workbook and get the first worksheet
const workbook = new xlsModule.Workbook();
const sheet = workbook.Worksheets.get(0);
// Add a double-arrow line - solid blue
let line = sheet.TypedLines.AddLine();
line.Top = 10;
line.Left = 20;
line.Width = 100;
line.Height = 0;
line.Color = xlsModule.Color.get_Blue();
line.BeginArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
line.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
// Add a single-arrow line - solid red
let line_1 = sheet.TypedLines.AddLine();
line_1.Top = 50;
line_1.Left = 30;
line_1.Width = 100;
line_1.Height = 100;
line_1.Color = xlsModule.Color.get_Red();
line_1.BeginArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineNoArrow;
line_1.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
// Add an elbow arrow connector
let line3 = sheet.TypedLines.AddLine();
line3.LineShapeType = xlsModule.LineShapeType.ElbowLine;
line3.Width = 30;
line3.Height = 50;
line3.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
line3.Top = 100;
line3.Left = 50;
// Add an elbow double-arrow connector
let line2 = sheet.TypedLines.AddLine();
line2.LineShapeType = xlsModule.LineShapeType.ElbowLine;
line2.Width = 50;
line2.Height = 50;
line2.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
line2.BeginArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
line2.Left = 120;
line2.Top = 100;
// Add a curved arrow connector
line3 = sheet.TypedLines.AddLine();
line3.LineShapeType = xlsModule.LineShapeType.CurveLine;
line3.Width = 30;
line3.Height = 50;
line3.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrowOpen;
line3.Top = 100;
line3.Left = 200;
// Add a curved double-arrow connector
line2 = sheet.TypedLines.AddLine();
line2.LineShapeType = xlsModule.LineShapeType.CurveLine;
line2.Width = 30;
line2.Height = 50;
line2.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrowOpen;
line2.BeginArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrowOpen;
line2.Left = 250;
line2.Top = 100;
// Save the workbook
const outputFileName = 'AddArrowLines.xlsx';
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
// Release resources
workbook.Dispose();
// Read the saved file from the VFS and trigger the download
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Add Arrow Lines</h1>
<button onClick={addArrowLines}>Start</button>
</div>
);
}
export default App;
Effect of inserting arrow-tipped lines:

Frequently Asked Questions
How do I retrieve and modify existing lines in a worksheet?
Reason: An Excel file with existing lines was imported, but it's unclear how to read or modify them.
Solution: Traverse the sheet.Shapes collection to retrieve line shape objects, then modify their properties via the ILineShape interface. For example, sheet.Shapes.get(0) gets the first shape, and after confirming it's a line type, you can modify properties like color, dash style, etc.
How do I delete lines from an Excel worksheet?
Reason: Need to remove excess lines that were created or imported.
Solution: Use sheet.Shapes.Remove(index) to delete a line object at a specified index from the shapes collection, or iterate through the Shapes collection to delete them one by one based on name or type conditions.
Get a Free License
Spire.XLS for JavaScript offers a 30-day full-featured free trial license with no functional limitations. Apply here to evaluate before purchasing.

Markdown is convenient for writing documentation, README files, notes, and other structured content. But when the content needs to be printed, archived, or shared in a fixed-layout format, PDF is often more practical.
In a React application, you can convert Markdown to PDF using Spire.Doc for JavaScript. The library runs through WebAssembly (WASM), allowing Markdown content to be processed and PDF files to be generated locally in the browser without sending files to a server.
This tutorial covers three common conversion scenarios:
- Convert a Markdown file to PDF with JavaScript
- Convert Markdown to PDF with custom page settings
- Convert a Markdown string to PDF with JavaScript
Set Up Spire.Doc for JavaScript in React
Before converting Markdown files, you need to integrate Spire.Doc for JavaScript into your React project and prepare the required WebAssembly runtime files.
For a detailed setup guide, see How to Integrate Spire.Doc for JavaScript in a React Project.
Step 1: Install the Package
Run the following command in your React project directory to install the required package from npm:
npm i spire.office
Step 2: Add the Required Runtime Files
Copy the following files and folders from node_modules/spire.office to your project's public directory:
_framework
spire.doc.js
Spire.Doc.Wasm.zip
spire.common.js
Spire.Common.Wasm.zip
The examples below also use CALIBRI.ttf for PDF text rendering. Place the font under:
public/static/font/
For file-based conversion, place the sample Markdown file under:
public/static/data/
The relevant project structure should look like this:
public/
├── _framework/
├── spire.doc.js
├── Spire.Doc.Wasm.zip
├── spire.common.js
├── Spire.Common.Wasm.zip
└── static/
├── data/
│ └── MarkdownExample.md
└── font/
└── CALIBRI.ttf
Note: The examples use process.env.PUBLIC_URL, which follows the Create React App convention. If your project uses Vite or another build tool, adjust the public asset paths accordingly.
Convert a Markdown File to PDF with JavaScript
Converting a Markdown file to PDF involves 4 main steps:
- Load the required font and Markdown file into the WASM virtual file system (VFS).
- Call
Document.LoadFromFile()withFileFormat.Markdownto load the Markdown file into aDocumentobject. - Call
Document.SaveToFile()withFileFormat.PDFto save the loaded document as a PDF file. - Read the generated PDF from the VFS and download it in the browser.
The following JavaScript example loads a .md file and saves it as a .pdf file:
import React, { useEffect, useState } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// Initialize the Spire.Doc WebAssembly module
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(
/* webpackIgnore: true */
`${publicUrl}/spire.doc.js`
);
const rawModule = spireModule.default || spireModule;
window.wasmModule =
typeof rawModule === 'function'
? await rawModule({
locateFile: (path) =>
path.endsWith('.wasm')
? `${publicUrl}/${path}`
: path
})
: rawModule;
setWasmModule(window.wasmModule);
} catch (error) {
console.error(
'Failed to load the Spire.Doc WASM module:',
error
);
}
})();
}, []);
// Download a file generated in the WASM virtual file system
const downloadVfsFile = (fileName, mimeType) => {
const fileData =
window.dotnetRuntime.Module.FS.readFile(fileName);
const blob = new Blob(
[fileData],
{ type: mimeType }
);
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
};
const convertMarkdownToPdf = async () => {
const docModule = window.wasmModule?.spiredoc;
if (!docModule) return;
const publicUrl = process.env.PUBLIC_URL || '';
// Load the font into the VFS
await window.spire.FetchFileToVFS(
'CALIBRI.ttf',
'/Library/Fonts/',
`${publicUrl}/static/font/`
);
const inputFileName = 'MarkdownExample.md';
const outputFileName = 'MarkdownToPDF.pdf';
// Load the Markdown file into the VFS
await window.spire.FetchFileToVFS(
inputFileName,
'',
`${publicUrl}/static/data/`
);
const doc = new docModule.Document();
try {
// Load the Markdown file
doc.LoadFromFile({
fileName: inputFileName,
fileFormat: docModule.FileFormat.Markdown
});
// Save the document as PDF
doc.SaveToFile({
fileName: outputFileName,
fileFormat: docModule.FileFormat.PDF
});
// Download the generated PDF
downloadVfsFile(
outputFileName,
'application/pdf'
);
} finally {
doc.Dispose();
}
};
return (
<div style={{ textAlign: 'center', padding: '40px' }}>
<h1>Convert Markdown to PDF</h1>
<button
onClick={convertMarkdownToPdf}
disabled={!wasmModule}
>
Convert and Download PDF
</button>
</div>
);
}
export default App;
Run the application and wait for the WASM module to finish loading. Then click Convert and Download PDF. The application will load MarkdownExample.md, convert it to MarkdownToPDF.pdf, and download the generated PDF in the browser.
Output
The generated PDF preserves the main Markdown structure, including headings, paragraphs, lists, and tables:

Convert Markdown to PDF with Custom Page Settings
The default page layout may not suit every document. A Markdown report containing a wide table, for example, may work better in landscape orientation, while printable documentation may require specific page sizes or margins.
After loading the Markdown file, you can access the document section and adjust its PageSetup properties before generating the PDF.
The following example sets the first section to A4 size, landscape orientation, and 50-point margins:
const section = doc.Sections.get_Item(0);
// Set page size
section.PageSetup.PageSize =
docModule.PageSize.A4();
// Set page orientation
section.PageSetup.Orientation =
docModule.PageOrientation.Landscape;
// Set page margins
section.PageSetup.Margins.All = 50;
To apply these settings during Markdown-to-PDF conversion, use the following function:
const convertMarkdownToPdfWithPageSettings = async () => {
const docModule = window.wasmModule?.spiredoc;
if (!docModule) return;
const publicUrl = process.env.PUBLIC_URL || '';
// Load the font into the VFS
await window.spire.FetchFileToVFS(
'CALIBRI.ttf',
'/Library/Fonts/',
`${publicUrl}/static/font/`
);
const inputFileName = 'MarkdownExample.md';
const outputFileName =
'MarkdownToPDFWithPageSettings.pdf';
// Load the Markdown file into the VFS
await window.spire.FetchFileToVFS(
inputFileName,
'',
`${publicUrl}/static/data/`
);
const doc = new docModule.Document();
try {
// Load the Markdown file
doc.LoadFromFile({
fileName: inputFileName,
fileFormat: docModule.FileFormat.Markdown
});
// Get the first section
const section = doc.Sections.get_Item(0);
// Set page size
section.PageSetup.PageSize =
docModule.PageSize.A4();
// Set landscape orientation
section.PageSetup.Orientation =
docModule.PageOrientation.Landscape;
// Set all margins to 50 points
section.PageSetup.Margins.All = 50;
// Save the document as PDF
doc.SaveToFile({
fileName: outputFileName,
fileFormat: docModule.FileFormat.PDF
});
// Download the generated PDF
downloadVfsFile(
outputFileName,
'application/pdf'
);
} finally {
doc.Dispose();
}
};
You can adjust the page size, orientation, and margins according to the content of your Markdown document.
Convert a Markdown String to PDF with JavaScript
Markdown does not always come from a physical .md file. In a React application, the content may already exist as a string from a Markdown editor, textarea, CMS, API response, or application state.
In this case, write the Markdown string to the WASM virtual file system using FS.writeFile(), then load the virtual .md file and convert it to PDF.
const convertMarkdownStringToPdf = async () => {
const docModule = window.wasmModule?.spiredoc;
if (!docModule) return;
const publicUrl = process.env.PUBLIC_URL || '';
// Load the font into the VFS
await window.spire.FetchFileToVFS(
'CALIBRI.ttf',
'/Library/Fonts/',
`${publicUrl}/static/font/`
);
const markdownString = `# Project Notes
This PDF was generated from **Markdown stored in a React string**.
## Tasks
- Review the draft
- Export the final copy
- Share the PDF
## Task Status
| Item | Status |
| --- | --- |
| Draft | Done |
| Review | Pending |
`;
const inputFileName = 'MarkdownInput.md';
const outputFileName = 'MarkdownStringToPDF.pdf';
// Write the Markdown string to the VFS
window.dotnetRuntime.Module.FS.writeFile(
inputFileName,
markdownString,
{ encoding: 'utf8' }
);
const doc = new docModule.Document();
try {
// Load the virtual Markdown file
doc.LoadFromFile({
fileName: inputFileName,
fileFormat: docModule.FileFormat.Markdown
});
// Save the document as PDF
doc.SaveToFile({
fileName: outputFileName,
fileFormat: docModule.FileFormat.PDF
});
// Download the generated PDF
downloadVfsFile(
outputFileName,
'application/pdf'
);
} finally {
doc.Dispose();
}
};
In an actual application, replace the sample string with the Markdown content from your existing data source:
const markdownString = editorValue;
or:
const markdownString = apiResponse.content;
The rest of the PDF conversion workflow remains the same.
Output

Why Are Fonts Loaded into the VFS?
PDF generation requires font data to render text correctly. In the examples above, CALIBRI.ttf is loaded into the WASM virtual file system before the Markdown document is processed:
await window.spire.FetchFileToVFS(
'CALIBRI.ttf',
'/Library/Fonts/',
`${publicUrl}/static/font/`
);
If the Markdown contains characters that are not supported by the selected font, load an appropriate font into /Library/Fonts/ as well.
This is particularly important when generating PDFs containing Chinese, Japanese, Korean, Arabic, or other multilingual text.
FAQs
Can I Convert a User-Uploaded Markdown File to PDF?
Yes. Instead of loading a fixed .md file from the public directory, you can read the uploaded Markdown file in the browser, write its content to the WASM virtual file system, and then load it with FileFormat.Markdown. This allows users to select and convert their own Markdown files directly in a React application.
Why Are Some Characters Missing from the Generated PDF?
This usually happens when the font required to display those characters is not available in the WASM environment. Load a font that supports the characters used in your Markdown into /Library/Fonts/ before generating the PDF. This is especially important for multilingual content.
What Should I Do If a Wide Markdown Table Is Cut Off?
Try switching the page to landscape orientation, reducing the margins, or using a larger page size before saving the document as PDF.
Why Are Images in My Markdown Missing from the PDF?
Markdown usually references images through a file path or URL rather than embedding the image data directly. Make sure the image files referenced in the Markdown are available during conversion and that their paths can be resolved by the conversion environment. Relative image paths may require additional handling depending on where the Markdown and image files are stored.
Does the Markdown-to-PDF Conversion Run Locally in the Browser?
Yes. In this React implementation, Spire.Doc for JavaScript runs through WebAssembly, while the Markdown input and generated PDF are processed through the browser-side virtual file system. A backend is not required for the conversion itself, although your application may still use one for file storage, authentication, or other server-side operations.
Conclusion
This article demonstrated how to convert Markdown to PDF with JavaScript in a React application, including basic file conversion, custom page settings, and conversion from Markdown strings.
With Spire.Doc for JavaScript, developers can load Markdown content, control PDF page layout, and generate PDF files directly in the browser through WebAssembly. This approach can be used for documentation tools, Markdown editors, reporting systems, and other applications that need to export Markdown content as PDF.
Get a Free License
To fully experience the capabilities of Spire.Doc for JavaScript without any evaluation limitations, you can request a free 30-day trial license.
Create Exploded Pie and Doughnut Charts in Excel with JavaScript in React
2026-09-10 08:16:03 Written by liu taliaPie charts and doughnut charts are the most intuitive chart types for showing the proportion of each data item. An exploded pie chart or exploded doughnut chart pulls all the slices apart, which makes every part stand out more clearly. Spire.XLS for JavaScript completes this directly in the browser based on WebAssembly, managing input/output files through a virtual file system (VFS), with no backend service required.
This article introduces two core features:
For installation and project configuration, refer to Integrating Spire.XLS for JavaScript in a React Project. The examples below assume Spire.XLS is installed and the WebAssembly module is initialized.
Create an Exploded Pie Chart
The slices of an exploded pie chart are separated from each other, which is suitable for highlighting the proportion of each data item. To create an exploded pie chart, follow these steps:
- Create a
Workbookobject and use theLoadFromFile()method to load the Excel file that contains the data. - Use the
Workbook.Worksheets.get()method to get the worksheet that contains the data. - Call the
Charts.Add()method to add a chart and set theChartTypetoExcelChartType.PieExploded. - Use the
Series.CategoryLabelsandSeries.Valuesproperties to specify the categories and values of the chart. - Set properties such as the chart title, position and data labels.
- Use the
Workbook.SaveToFile()method to save the workbook.
Here is a complete code example showing how to create an exploded pie chart from the product sales data in a worksheet in React:
function App() {
const createExplodedPieChart = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
// Check whether the module is ready
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// Load the font and Excel file into the VFS
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'SalesData.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// Load the workbook and get the worksheet that contains the data
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
const sheet = workbook.Worksheets.get(0);
// Add a chart and set its chart type to an exploded pie chart
const chart = sheet.Charts.Add();
chart.ChartType = xlsModule.ExcelChartType.PieExploded;
// Set the data range and the title of the chart
chart.DataRange = sheet.Range.get("B2:B7");
chart.SeriesDataFromRange = false;
chart.ChartTitle = "Product Sales Share";
chart.ChartTitleArea.IsBold = true;
chart.ChartTitleArea.Size = 12;
// Set the category labels and the values of the chart, and show the value labels
const cs = chart.Series.get(0);
cs.CategoryLabels = sheet.Range.get("A2:A7");
cs.Values = sheet.Range.get("B2:B7");
cs.DataPoints.DefaultDataPoint.DataLabels.HasValue = true;
// Set the position of the chart
chart.LeftColumn = 4;
chart.TopRow = 1;
chart.RightColumn = 15;
chart.BottomRow = 25;
// Hide the background of the plot area and set the position of the legend
chart.PlotArea.Fill.Visible = false;
chart.Legend.Position = xlsModule.LegendPositionType.Right;
// Save the document
const outputFileName = 'ExplodedPieChart_output.xlsx';
workbook.SaveToFile({ fileName: outputFileName });
// Release resources
workbook.Dispose();
// Read the converted file from the VFS and trigger a download
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Create Exploded Pie Chart</h1>
<button onClick={createExplodedPieChart}>
Start
</button>
</div>
);
}
export default App;
After running the code, you can see the effect of the exploded pie chart:

Create an Exploded Doughnut Chart
A doughnut chart is similar to a pie chart, but it has a hole in the center and can also show the proportion of each part in the whole. An exploded doughnut chart further pulls the slices apart. To create an exploded doughnut chart, follow these steps:
- Create a
Workbookobject and use theLoadFromFile()method to load the Excel file that contains the data. - Use the
Workbook.Worksheets.get()method to get the worksheet that contains the data. - Call the
Charts.Add()method to add a chart and set theChartTypetoExcelChartType.DoughnutExploded. - Use the
Series.CategoryLabelsandSeries.Valuesproperties to specify the categories and values of the chart. - Set properties such as the chart title, position and data labels.
- Use the
Workbook.SaveToFile()method to save the workbook.
Here is a complete code example showing how to create an exploded doughnut chart from the product sales data in a worksheet in React:
function App() {
const createExplodedDoughnutChart = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
// Check whether the module is ready
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// Load the font and Excel file into the VFS
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'SalesData.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// Load the workbook and get the worksheet that contains the data
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
const sheet = workbook.Worksheets.get(0);
// Add a chart and set its chart type to an exploded doughnut chart
const chart = sheet.Charts.Add();
chart.ChartType = xlsModule.ExcelChartType.DoughnutExploded;
// Set the data range and the title of the chart
chart.DataRange = sheet.Range.get("B2:B7");
chart.SeriesDataFromRange = false;
chart.ChartTitle = "Sales Share by Product";
chart.ChartTitleArea.IsBold = true;
chart.ChartTitleArea.Size = 12;
// Set the category labels and the values of the chart, and show the value labels
const cs = chart.Series.get(0);
cs.CategoryLabels = sheet.Range.get("A2:A7");
cs.Values = sheet.Range.get("B2:B7");
cs.DataPoints.DefaultDataPoint.DataLabels.HasValue = true;
// Set the position of the chart
chart.LeftColumn = 4;
chart.TopRow = 1;
chart.RightColumn = 15;
chart.BottomRow = 25;
// Hide the background of the plot area and set the position of the legend
chart.PlotArea.Fill.Visible = false;
chart.Legend.Position = xlsModule.LegendPositionType.Right;
// Save the document
const outputFileName = 'ExplodedDoughnutChart_output.xlsx';
workbook.SaveToFile({ fileName: outputFileName });
// Release resources
workbook.Dispose();
// Read the converted file from the VFS and trigger a download
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Create Exploded Doughnut Chart</h1>
<button onClick={createExplodedDoughnutChart}>
Start
</button>
</div>
);
}
export default App;
After running the code, you can see the effect of the exploded doughnut chart:

FAQ
The created chart is blank with no slices
Cause: The chart has no valid data series. For example, the DataRange or Values points to an empty range or a range without numbers, so the chart has no data to draw.
Solution: Assign a data range that contains the data to the chart, for example:
chart.DataRange = sheet.Range.get("A1:B7");
const cs = chart.Series.get(0);
cs.CategoryLabels = sheet.Range.get("A2:A7");
cs.Values = sheet.Range.get("B2:B7");
Want to show percentages instead of values in the data labels
Cause: Pie and doughnut charts are usually used to show proportions, but the data labels show values by default, or the percentage labels are not enabled.
Solution: Disable the value labels and enable the percentage labels, for example:
const cs = chart.Series.get(0);
cs.DataPoints.DefaultDataPoint.DataLabels.HasValue = false;
cs.DataPoints.DefaultDataPoint.DataLabels.HasPercentage = true;
Obtain a Free License
Spire.XLS for JavaScript offers a 30-day full-featured free trial license with no functional limitations. Apply here to evaluate before purchasing.