Spire.Doc is a professional Word .NET library specifically designed for developers to create, read, write, convert and print Word document files. Get free and professional technical support for Spire.Doc for .NET, Java, Android, C++, Python.

Mon Sep 21, 2026 11:00 am

I am using version 9.10.0 of Spire.Office

The TOC (Table of Contents) is not updating correctly when generating a .docx file.

I am using: document.UpdateTableOfContents();

Here is the complete code:

C#
//Actualizar Summary
try
{
document.UpdateTableOfContents();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error updating table of contents in EconomicMemoryIndex");
}

var TempStream = new MemoryStream();
//Create File
document.SaveToStream(TempStream, FileFormat.Docx2013);
var bufferresult = TempStream.GetBytes();

//kill stream
TempStream.Close();
//Return Buffer
return await Task.FromResult(bufferresult);
The TOC is not updating correctly. It shows incorrect page numbers for some sections. For example, in the TOC it appears as page 9 when it should be page 10.

Is there a way to resolve this correctly?

Thank you in advance for your help!

Thank you for your assistance.

david.garrosa
 
Posts: 6
Joined: Mon Sep 21, 2026 10:35 am

Tue Sep 22, 2026 10:14 am

Hello,

Thank you for your inquiry.

The latest version of Spire.Office for .NET is currently 11.8.0 (https://www.e-iceblue.com/Download/download-office-for-net-now.html). Please try using the latest version.
If the issue persists, in order to help us reproduce and investigate the problem, please provide your input Word document. Thank you for your assistance.

Sincerely,
Amy
E-iceblue support team
User avatar

amy.zhao
 
Posts: 3043
Joined: Wed Jun 27, 2012 8:50 am

Tue Sep 22, 2026 12:51 pm

Thank you for your help. I'm attaching the document for more context on what's happening. It's still not working with the latest version—I'm still getting the same TOC error.

david.garrosa
 
Posts: 6
Joined: Mon Sep 21, 2026 10:35 am

Wed Sep 23, 2026 7:04 am

Hello,

Thanks for your sharing.

I tested your document using the code below with the Spire.Office 11.8.0 package. When I opened the generated result document in MS Word 2019, I could see that the page numbers in the table of contents were correctly updated to 10.

Code: Select all
Document document = new Document();
document.LoadFromFile(path + "1.docx");
document.UpdateTableOfContents();
document.SaveToFile(path + "2.docx", Spire.Doc.FileFormat.Docx2013);


I have uploaded the result document generated on my end. Please take a look. You could also share your result document so I can check it. It's possible that the discrepancy is caused by the tool used to view the Word document.

Sincerely,
Amy
E-iceblue support team
User avatar

amy.zhao
 
Posts: 3043
Joined: Wed Jun 27, 2012 8:50 am

Wed Sep 23, 2026 9:51 am

This refers to a business subscription for which we do not hold a Spire.Office licence for the LTS version, but rather for the version I currently have.
The same applies to the Office suite we use to run Word.
This version is: ‘Word 365, version 2608 (build 16.0.20326.20072), 64-bit’.

This is something that is not up to me, but depends on the company, and I cannot change it.

Is there a solution for this version of Spire and Word?
Is this a known issue?

Thank you again for your help.

david.garrosa
 
Posts: 6
Joined: Mon Sep 21, 2026 10:35 am

Thu Sep 24, 2026 9:15 am

Hello,

Thank you for your feedback.
We need to confirm again whether the Word document you provided to us is the document after your UpdateTableOfContents() result? Through the following code, whether using version 9.10.0 or the latest 11.8.0, the updated result is the same as the one provided to you yesterday, even when opened in Office 365, the effect is also consistent as shown in the attached screenshot.
Code: Select all
Document document = new Document();
document.LoadFromFile(@"Memoria_económica_N-IDI22.docx");
document.UpdateTableOfContents();
document.SaveToFile(@"output.docx", Spire.Doc.FileFormat.Docx2013);

If there are any differences between our testing and yours, please let us know. Thank you in advance.

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1533
Joined: Wed Apr 25, 2018 3:20 am

Tue Sep 29, 2026 8:31 am

It works correctly for you because you import the generated document and call the method again. We generate the document from scratch; I can’t update it in the same way because the document doesn’t exist at that point.

I’ll copy over all the code we use to generate the file… although it’s huge and calls various methods, but perhaps this will give you a better context.

Thanks again for your help.


public async Task<byte[]> GenerateFile(Guid missionId, string language, IDictionary<string, object> parameters)
{
Func<string, string> t = key => _translationService.Translate(key, null, language);

var context = _dbContextFactory.GetContext();

var mission = context.Set<Mission>().Include(x => x.Regime).FirstOrDefault(t => t.Id == missionId);
decimal IVAPercentage = await _percentageService.GetIvaPercent(missionId) / 100;
var companyId = mission.CompanyId;
var company = context.Set<Company>().FirstOrDefault(t => t.Id == companyId);
bool includeAnnotation = (bool)parameters["IncludeAnnotation"];
bool? includeIndividualCostStaff = (bool?)parameters["IncludeIndividualCostStaff"];

bool isGlobalTechnicalMemory = parameters.ContainsKey("IsGlobalTechnicalMemory");

//Identificación de proyectos
List<Project> projects = await context.Set<Project>().Include("Qualification").Where(t => t.MissionId == mission.Id && t.QualificationId != null && !t.IsDeleted).OrderBy(p => p.Acronym).ToListAsync();

//Projectos AUTO
var projectsAUTO = projects.Where(p => p.Strategy == Strategy.Expertise).ToList();

bool isProjectsAUTO = projectsAUTO.Count > 0;

var stream = GetTemplateStream(isGlobalTechnicalMemory, includeAnnotation, isProjectsAUTO);

Document document = new Document(stream);

document.addStylesDocument();

//Portada
var frontPage = new Frontpage(_fileStorageService, _logger);
await frontPage.GenerateFrontPage(document, company, mission);

//Datos generales
var generalData = new GeneralData();
generalData.GenerateGeneralData(document, mission);

var technicalMemories = await context.Set<TechnicalMemory>().Include("Project").Where(t => t.Project.MissionId == missionId && t.Project.Strategy == Strategy.Expertise).ToListAsync();

if (isGlobalTechnicalMemory && isProjectsAUTO)
{
generalData.GenerateTechnicalSpecialist(document, mission, projectsAUTO, technicalMemories, t);
}

var projectsID = projects.Where(p => p.Qualification.Title == "I+D" && p.Qualification.Title != "I+D+I").OrderBy(p => p.Acronym).ToList();
var projectsIT = projects.Where(p => p.Qualification.Title == "IT" && p.Qualification.Title != "I+D+I").OrderBy(p => p.Acronym).ToList();
var projectsITID = projects.Where(p => p.Qualification.Title == "I+D+I" && p.Qualification.Title != "IT" && p.Qualification.Title != "I+D").OrderBy(p => p.Acronym).ToList();
var projectList = new ProjectList();
projectList.GenerateProjectList(document, projectsID, projectsIT, projectsITID);

//Memoria Económica
string projectsText = projects.Count() > 1 ? "de los proyectos" : "del proyecto";
var economicMemorySection = new EconomicMemorySection();
economicMemorySection.GenerateEconomicMemorySection(document, mission, projectsText);

#region Calculo deduccion

// New Method

var deductionCalculation = new DeductionReport("");

//Staff
var staffSection = new StaffSection();
await staffSection.GenerateStaffSection(document, mission.Id, projects, deductionCalculation, includeIndividualCostStaff, context);

//Collaborations
var collaborationsSection = new CollaborationsSection(_expensesService);
await collaborationsSection.GenerateCollaborationsSection(document, mission, projects, deductionCalculation, context);

////Consumables
var consumblessSection = new ConsumablesSection();
await consumblessSection.GenerateConsumablesSection(document, mission, projects, deductionCalculation, context);

//Assets
var assetsSection = new AssetsSection(_assetDataService, _percentageService);
await assetsSection.GenerateAssetsSection(document, mission, projects, deductionCalculation, context);

//Otros gastos
var otherExpensesSection = new OtherExpensesSection();
await otherExpensesSection.GenerateOtherExpensesSection(document, mission, projects, deductionCalculation, context);

//Ayudas
var grantsSection = new GrantsSection(_grantsDataService);
await grantsSection.GenerateGrantsSection(mission, projects, deductionCalculation, context);

//Gasto por proyecto
var expensePerProjectSection = new ExpensePerProjectSection(_expensesPerProjectService);
ExpensesSectionResult expensesSectionResult = await expensePerProjectSection.GeneratExpensePerProjectSection(document, mission, projects, deductionCalculation);

//Deducciones
var deductionsSection = new DeductionSection(_deductionService);
DeductionSectionResult deductionSectionResult = await deductionsSection.GenerateDeductionSection(document, mission, projects, expensesSectionResult.ExpensesSummary, deductionCalculation);

deductionCalculation.CloseSections();

if (deductionCalculation.SectionCount > 0)
{
var file = await deductionCalculation.GenerateFile();
var replace = new Document(file);
document.Replace("{deductionCalculation}", replace, true, true);
}
else
document.Replace("{deductionCalculation}", "", true, true);

#endregion Calculo deduccion

bool? includeAnnexeIII = (bool?)parameters["IncludeAnnexeIII"];
// Annexe III
var annexeIII = new AnnexeIIISection(_recapDataService);
if (includeAnnexeIII.GetValueOrDefault())
{
await annexeIII.GenerateAnnexeIII(document, mission);
}
else
{
RemoveAnnexeIIIBlock(document);
}

//Recap
var recap = new RecapSection(_recapDataService);
await recap.GenerateRecap(document, mission);

var versions = context.Set<Version>().Include(x => x.Mission)
.Where(x => x.OriginalMissionId == missionId &&
(x.VersionType == VersionType.Precertificada || x.VersionType == VersionType.Certificada || x.VersionType == VersionType.Motivada))
.OrderBy(x => x.VersionType).ToList();

//Desviations
if (isGlobalTechnicalMemory)
{
var desviations = new DesviationsSection(_expensesPerProjectService, _deductionService);
await desviations.GenerateDesviations(document, projects, includeAnnotation, isGlobalTechnicalMemory, mission, versions);
}

#region Annotations

//if (includeAnnotation)
//{
// // se pidio el 247672024 que salieran los valores de los gastos en vez de las deducciones
//
// var annotations = new AnnotationsSection();
// var deductionAnnotationsStrem = await annotations.GenerateAnnotations(missionId, expensesSectionResult, company.Title, context);
//
// Document deductionAnnotationsStreamDocument = new Document(deductionAnnotationsStrem);
// document.Replace("{DeductionAnnotationSummary}", deductionAnnotationsStreamDocument, false, false);
// document.Replace("{IncludeAnnotation}", "", false, false);
//}

#endregion Annotations

#region globalSheets

#region regimenDesc

string regimen = mission.Regime.Title;
string regimenDescription = string.Empty;
string regimenDesc1 = string.Empty;
string regimenDesc2 = string.Empty;

switch (regimen)
{
case "Estatal":
regimenDescription = "Real Decreto 1432 / 2003, de 21 de Noviembre, por el que se regula la emisión por el Ministerio de Ciencia y Tecnología de informes motivados relativos al cumplimiento de requisitos científicos y tecnológicos a efectos de la aplicación e interpretación de deducciones fiscales por actividades de investigación y desarrollo e innovación tecnológica.";
regimenDesc1 = "Ley 27/2014, de 27 de noviembre, del Impuesto sobre Sociedades. Artículo 35.";
regimenDesc2 = string.Empty;
break;

case "Navarra":
regimenDescription = "Ley Foral 26/2016, de 28 de diciembre, del Impuesto sobre Sociedades.";
regimenDesc1 = "Real Decreto 1432 / 2003, de 21 de Noviembre, por el que se regula la emisión por el Ministerio de Ciencia y Tecnología de informes motivados relativos al cumplimiento de requisitos científicos y tecnológicos a efectos de la aplicación e interpretación de deducciones fiscales por actividades de investigación y desarrollo e innovación tecnológica.";
regimenDesc2 = "Ley 27/2014, de 27 de noviembre, del Impuesto sobre Sociedades. Artículo 35.";
break;

case "Canarias":
regimenDescription = "Ley 20/1991, Art. 94 que regula el régimen económica fiscal Canario.";
regimenDesc1 = "Real Decreto 1432 / 2003, de 21 de Noviembre, por el que se regula la emisión por el Ministerio de Ciencia y Tecnología de informes motivados relativos al cumplimiento de requisitos científicos y tecnológicos a efectos de la aplicación e interpretación de deducciones fiscales por actividades de investigación y desarrollo e innovación tecnológica.";
regimenDesc2 = "Ley 27/2014, de 27 de noviembre, del Impuesto sobre Sociedades. Artículo 35.";
break;

case "Alava":
regimenDescription = "Norma Foral 37/2013 de 13 de diciembre, de las Juntas Generales de Araba del Impuesto sobre Sociedades";
regimenDesc1 = string.Empty;
regimenDesc2 = string.Empty;
break;

case "Vizcaya":
regimenDescription = "Norma Foral 11/2013 de 5 de diciembre, de las Juntas Generales de Bizkaia del Impuesto sobre Sociedades";
regimenDesc1 = string.Empty;
regimenDesc2 = string.Empty;
break;

case "Guipuzcoa":
regimenDescription = "Norma Foral 2/2014 de 17 de enero, de las Juntas Generales de Gipuzkoa del Impuesto sobre Sociedades";
regimenDesc1 = string.Empty;
regimenDesc2 = string.Empty;
break;

default:
regimenDescription = string.Empty;
regimenDesc1 = string.Empty;
regimenDesc2 = string.Empty;
break;
}

if (!string.IsNullOrEmpty(regimenDescription))
{
document.Replace("{regimenDesc}", regimenDescription, false, false);
}
else
{
document.RemoveParagraphWithMarker("{regimenDesc}");
}

if (!string.IsNullOrEmpty(regimenDesc1))
{
document.Replace("{regimenDesc-2}", regimenDesc1, false, false);
}
else
{
document.RemoveParagraphWithMarker("{regimenDesc-2}");
}

if (!string.IsNullOrEmpty(regimenDesc2))
{
document.Replace("{regimenDesc-3}", regimenDesc2, false, false);
}
else
{
document.RemoveParagraphWithMarker("{regimenDesc-3}");
}

#endregion regimenDesc

if (isGlobalTechnicalMemory)
{
if (!string.IsNullOrEmpty(regimenDescription))
{
document.Replace("{regimenDesc}", regimenDescription, false, false);
}
else
{
document.RemoveParagraphWithMarker("{regimenDesc}");
}

if (!string.IsNullOrEmpty(regimenDesc1))
{
document.Replace("{regimenDesc-2}", regimenDesc1, false, false);
}
else
{
document.RemoveParagraphWithMarker("{regimenDesc-2}");
}

if (!string.IsNullOrEmpty(regimenDesc2))
{
document.Replace("{regimenDesc-3}", regimenDesc2, false, false);
}
else
{
document.RemoveParagraphWithMarker("{regimenDesc-3}");
}

bool certificateShow = projects.Any(x => x.Strategy == Strategy.IMV || x.Strategy == Strategy.NoIVMCertificate);
bool imvShow = projects.Any(x => x.Strategy == Strategy.IMV);

var projectsId = projects.Select(x => x.Id).ToList();
bool hasTechMem = context.Set<TechnicalMemory>().Any(x => projectsId.Contains(x.ProjectId) && x.IsFinalVersion);
if (hasTechMem)
{
document.Replace("{certificadoMemTec}", "", false, true);
}
else
{
document.RemoveParagraphWithMarker("{certificadoMemTec}");
}

if (certificateShow)
{
document.Replace("{certificadoDesc}", "", false, true);
}
else
{
document.RemoveParagraphWithMarker("{certificadoDesc}");
}

if (imvShow)
{
document.Replace("{IMVDesc}", "", false, true);
}
else
{
document.RemoveParagraphWithMarker("{IMVDesc}");
}
}

#endregion globalSheets

// Copy Header and Footer
//CopyHeaderFooter(document);

//Actualizar Summary
try
{
document.UpdateTableOfContents();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error updating table of contents in EconomicMemoryIndex");
}

var TempStream = new MemoryStream();
//Create File
document.SaveToStream(TempStream, FileFormat.Docx2013);
var bufferresult = TempStream.GetBytes();

//kill stream
TempStream.Close();
//Return Buffer
return await Task.FromResult(bufferresult);
}

david.garrosa
 
Posts: 6
Joined: Mon Sep 21, 2026 10:35 am

Tue Sep 29, 2026 10:07 am

Hello,

Thank you for your feedback. I'll create a project to simulate your code for testing, and then get back to you with my findings.

Sincerely,
Amy
E-iceblue support team
User avatar

amy.zhao
 
Posts: 3043
Joined: Wed Jun 27, 2012 8:50 am

Wed Sep 30, 2026 9:54 am

Thank you very much for your support.

david.garrosa
 
Posts: 6
Joined: Mon Sep 21, 2026 10:35 am

Wed Sep 30, 2026 10:10 am

Hello,

Thank you for your patience.

I simulated your code to test updating the TOC field, but I still cannot reproduce the issue of incorrect page numbers. Could you please provide your complete executable project to help us reproduce and investigate this issue? If the data involves privacy concerns, you can send it to [email protected]. Thanks.

Sincerely,
Amy
E-iceblue support team
User avatar

amy.zhao
 
Posts: 3043
Joined: Wed Jun 27, 2012 8:50 am

Thu Oct 01, 2026 1:22 pm

Thank you for your help and all your efforts.

As I am unable to grant access to download the repo, we cannot proceed, so we can close this post.

Thank you very much again for all your efforts.

david.garrosa
 
Posts: 6
Joined: Mon Sep 21, 2026 10:35 am

Fri Oct 02, 2026 1:53 am

Hello,

Thanks for your reply.
Are you referring to our latest Spire.Office when you mention the repository? If you could send us a minimal demo that reproduces your issue via email, we might be able to assist further. Thank you for your understanding.

Sincerely,
William
E-iceblue support team
User avatar

William.Zhang
 
Posts: 757
Joined: Mon Dec 27, 2021 2:23 am

Return to Spire.Doc