Posted 6 October 2026, 8:13 am EST
Hello,
When the & operator or a text function such as CONCATENATE converts a number to text, SpreadJS always uses a dot as decimal separator, whatever the culture. The opposite conversion, text to number, does follow the culture. With a culture that uses a comma (fr-FR for example), the two conversions do not match:
- Wrong display: A1&" pts" returns “3.6 pts” instead of “3,6 pts” (Excel in French returns “3,6 pts”).
- The round trip fails: VALUE(A1&“”) returns #VALUE!.
- With ExcelCompatibleCalcMode = true, criteria built by concatenation are not read as numbers: COUNTIF(A1:A3,“>=”&A1) returns 0 instead of 3, and SUMIF(A1:A3,“<”&4.5) returns 0 instead of 7.6.
Version: SpreadJS 19.2.3. The fr-FR culture from sjs-globalization gives the same results.
Code to reproduce
// A culture with a comma as decimal separator
const culture = new GC.Spread.Common.CultureInfo();
culture.NumberFormat.numberDecimalSeparator = ",";
culture.NumberFormat.numberGroupSeparator = " ";
culture.NumberFormat.listSeparator = ";";
culture.NumberFormat.arrayListSeparator = "\\";
culture.NumberFormat.arrayGroupSeparator = ";";
GC.Spread.Common.CultureManager.addCultureInfo("fr-fr", culture);
GC.Spread.Common.CultureManager.culture("fr-fr");
const spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
const sheet = spread.getActiveSheet();
sheet.setArray(0, 0, [[3.6], [4], [5.5]]);
const formulas = [
'A1&" pts"',
'CONCATENATE(A1," pts")',
'VALUE(A1&"")',
'COUNTIF(A1:A3,">="&A1)',
'SUMIF(A1:A3,"<"&4.5)',
'"3,6"*1',
];
formulas.forEach((formula, row) => sheet.setFormula(row, 1, formula));
for (const mode of [false, true]) {
GC.Spread.CalcEngine.ExcelCompatibleCalcMode = mode;
spread.calculate(GC.Spread.Sheets.CalculationType.all);
console.log(mode, formulas.map((formula, row) => sheet.getValue(row, 1)));
}
// false: ["3.6 pts", "3.6 pts", #VALUE!, 3, 7.6, 3.6]
// true: ["3.6 pts", "3.6 pts", #VALUE!, 0, 0, 3.6]
Results
“Mode off” means ExcelCompatibleCalcMode = false, “mode on” means ExcelCompatibleCalcMode = true. Numbers are shown as JavaScript values.
Formula Mode off Mode on Expected (Excel fr-FR)
=A1&" pts" 3.6 pts 3.6 pts 3,6 pts
=CONCATENATE(A1," pts") 3.6 pts 3.6 pts 3,6 pts
=VALUE(A1&"") #VALUE! #VALUE! 3.6
=COUNTIF(A1:A3,">="&A1) 3 0 3
=SUMIF(A1:A3,"<"&4.5) 7.6 0 7.6
="3,6"*1 3.6 3.6 3.6
The last line shows that text to number conversion does use the culture.
Expected behavior
Number to text conversions, both by the & operator and in text function arguments, should use the decimal separator of the current culture, as Excel does. The result can then be converted back to a number in the same culture.
Thank you for your help.
