question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TotalsRowFunction issue

See original GitHub issue
  • Bug

Version of ClosedXML

Latest from Nuget: 0.94.2

What is the current behavior?

It seems like TotalsRowFunction fails to create a valid cell reference when these two conditions are met:

  • The table column name has spaces (e.g., “AB CD”)
  • The name of the sheet where the table exists also has spaces (e.g., “Two words”)

When you open the generated file in Excel you are prompted to accept the repair actions. The XML report includes a message like “Repaired Records: Table from /xl/tables/table2.xml part (Table)”

The resulting formula in the Totals cell is “=SUBTOTAL(109,Two #REF!)”

What is the expected behavior or new feature?

The formula in the Totals cell should be: “=SUBTOTAL(109,[AB CD])”

Did this work in previous versions of our tool? Which versions?

As far as I know it was working fine with version 0.92.

Reproducibility

This issue seems to be related to case #773 (Bug with TotalsRowFunction). I adapted the code provided by healkar01 to reproduce the problem. Look at the “Two words2” sheet in the generated XLS file to see the issue in the Grand Total cell (B11)

Code to reproduce problem:

void Main()
{
	XLWorkbook wb = new XLWorkbook();

	InsertDataTable(wb, "OneWord", GenerateData(useMultiWordColumn: false));
	InsertDataTable(wb, "OneWord2", GenerateData(useMultiWordColumn: true));
	InsertDataTable(wb, "Two words", GenerateData(useMultiWordColumn: false));
        // the line below reproduces the issue
	InsertDataTable(wb, "Two words2", GenerateData(useMultiWordColumn: true)); 

	wb.SaveAs($@"C:\{DateTime.Now.ToString("yyyyMMdd-HHmmss")}-ClosedXml-Issue.xlsx");
}

static DataTable GenerateData(bool useMultiWordColumn)
{
	var columnName = useMultiWordColumn ? "AB CD" : "ABCD";
	DataTable dt = new DataTable();
	dt.Clear();
	dt.Columns.Add("Service", typeof(String));
	dt.Columns.Add(columnName, typeof(Int32));

	for (int i = 1; i < 10; i++)
	{
		DataRow dtRow = dt.NewRow();
		dtRow["Service"] = "Service " + i;
		dtRow[columnName] = 500;
		dt.Rows.Add(dtRow);
	}
	return dt;
}

static void InsertDataTable(XLWorkbook wb, string sheetName, DataTable dt)
{
	var ws = wb.Worksheets.Add(sheetName);

	// Insert our datatable into the data sheet at cell 1,1
	var table = ws.Cell(1, 1).InsertTable(dt, sheetName, true);

	ws.Columns().AdjustToContents();
	table.ShowTotalsRow = true;
	foreach (var field in table.Fields)
	{
		if (field.Index > 0 && field.Name != "")
		{
			field.TotalsRowFunction = XLTotalsRowFunction.Sum;
		}
	}

	table.Field(0).TotalsRowLabel = "Grand Total";
}

Thanks! This is a great tool, thank you for providing it. Let me know if you need more information.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
igiturcommented, Apr 21, 2020

@tegrit-joe-trupiano The bug is that ClosedXML isn’t generating the second table’s name correctly. So both tables end up with Table1 as their names. You can easily workaround this by manually specifying the table names in the InsertTable() overload. It’s arguably better practice always to do that anyway. I’ll prepare a fix for this though.

0reactions
tegrit-joe-trupianocommented, Apr 20, 2020

Hi igitur, thanks for the reply I was able to reproduce this bug and have the code sample attached with just what is need to reproduce. The bug seems to require a second tab as with one tab I can not reproduce the bug.

Description - Class of items for displaying in the excel sheet

        public class Item
        {
            public string Employer { get; set; }
            public int General { get; set; }
            public decimal GeneralPercent { get; set; }
            public int Safety { get; set; }
            public decimal SafetyPercent { get; set; }
            public int Total => General + Safety;
        }

Description - Main in console app. Outputs the excel to bin. The issue is in the renaming of the field in the second tab. Issue does not happen when just one tab is present and that tab contains the same renaming.

        static void Main(string[] args)
        {
            var items = new List<Item>
            {
                new Item {Employer = "Employer 1", General = 60, GeneralPercent = 0.06M, Safety = 60, SafetyPercent = 0.06M},
                new Item {Employer = "Employer 2", General = 940, GeneralPercent = 0.94M, Safety = 940, SafetyPercent = 0.94M}
            };

            using (var workbook = new XLWorkbook())
            {
                var ws1 = workbook.Worksheets.Add("Tab 1");

                var tab1table1 = ws1.Cell(1, 1).InsertTable(items.AsEnumerable());
                tab1table1.ShowTotalsRow = true;
                tab1table1.Field(0).TotalsRowLabel = "Totals";
                foreach (var field in tab1table1.Fields.Where(f => f.Index > 0))
                {
                    field.TotalsRowFunction = XLTotalsRowFunction.Sum;
                }

                var ws2 = workbook.Worksheets.Add("Tab 2");

                var tab2table1 = ws2.Cell(1, 1).InsertTable(items.AsEnumerable());
                tab2table1.ShowTotalsRow = true;
                tab2table1.Field(0).TotalsRowLabel = "Totals";
                foreach (var field in tab2table1.Fields.Where(f => f.Index > 0))
                {
                    if (field.Name == "GeneralPercent")
                    {
                        field.Name = "General %";
                    }

                    field.TotalsRowFunction = XLTotalsRowFunction.Sum;
                }

                Assembly asm = Assembly.GetExecutingAssembly();
                var path = Path.Combine(System.IO.Path.GetDirectoryName(asm.Location), "items.xlsx");

                workbook.SaveAs(path);
            }
        }

I can open a new bug if needed. Sorry if I came off as pushy or impatient above. New to github so just learning.

Thanks

Edit - Added more detail

Read more comments on GitHub >

github_iconTop Results From Across the Web

Not clear how to configure a Table Totals Row - openpyxl
totalsRowFunction = 'count' >>> ws.add_table(tab) >>> wb.save("table.xlsx"). That all works but, when I try to open table.xlsx in Excel 2013 ...
Read more >
TotalsRowFormula Class (DocumentFormat.OpenXml. ...
This element contains a custom formula for aggregating values from the column. Each tableColumn has a totalsRowFunction that can be used for simple...
Read more >
Adding Summation Row - GemBox.Spreadsheet
I am generating invoices from a SQL Table into Gembox Spreadsheet. I formatted all the data in the sheet as a table, and...
Read more >
Create total row in xlsx file using NPOI
The problem is that I am also trying to add a Total Row. But for some reason, the cell with the value of...
Read more >
EPPlus Issue Tracker Rss Feed - RSSing.com
I think I found a bug in the 4.0 beta. It has to do with the TotalsRowFunction on a table. I've attached a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found