Hi,
We reviewed the custom LET formatter you shared. Based on our investigation, the custom formatter itself is not responsible for converting 2026 into an OADate.
The key factor is the existing date formatter cached in the cell’s style:
“formatCached”: “yyyy/m/d”
Why the conversion occurs
When 2026 is copied as plain text from Notepad and pasted into the target cell, SpreadJS processes the pasted value based on the formatter associated with the destination cell.
Since the destination cell has a date formatter (yyyy/m/d), the numeric text 2026 is interpreted as an OADate serial number. Therefore, the underlying value becomes a Date value and is serialized in the .sjs file as:
“value”: “/OADate(2026)/”
The LET formatter you provided is primarily responsible for formatting/displaying the cell value. There is no specific part of the formula that instructs SpreadJS to convert the incoming 2026 into an OADate.
How formatCached is involved
The formatCached entry is an internal cached representation of the formatter associated with the cell’s style. It is used to avoid repeatedly parsing the formatter during processing/rendering.
For example, the following code is sufficient to reproduce the behavior:
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
var sheet = spread.getSheet(0);
// Apply a date formatter to the cell
sheet.getCell(0, 0).formatter("yyyy/m/d");
After saving the workbook as an .sjs file and inspecting style.json, you can find the corresponding formatter information.
If you then paste the plain text 2026 from Notepad into that cell, the value is interpreted according to the date formatter and becomes an OADate value.
The date formatter can also be introduced through other operations, such as:
Applying a date format directly using the API.
Applying a date format through the Format Cells dialog in Designer.
Importing an Excel or SJS file containing date-formatted cells.
Copying formatting from another date-formatted cell.
Applying a date formatter at the row, column, or sheet default-style level, which can then be inherited by the cell.
Therefore, if the yyyy/m/d formatter was not intentionally assigned to this cell, we recommend checking whether it is being inherited from a row, column, or sheet-level style.
Recommended approach
If the target cell is intended to contain numeric values, you can reset its formatter to General:
sheet.setFormatter(row, col, “General”);
You can also check the row, column, and sheet-level styles to ensure that a date formatter is not being inherited.
In summary, the custom LET formatter is not the cause of the OADate conversion. The conversion is driven by the date formatter associated with the destination cell’s style, which is reflected by the formatCached: “yyyy/m/d” entry.
We hope this clarifies the relationship between the custom formatter, the cached formatter, and the OADate conversion.
If you are still facing the issue or feel that your questions have not been fully addressed, please share the file with us so that we can investigate it further.
If the file contains confidential or sensitive information, please replace it with dummy data while keeping the same structure and behavior, and then share the modified file with us.
Regards,
Priyam