···17641764 value = value.getTime();
17651765 }
1766176617671767+ // Safety net: extract text from objects to prevent [object Object] display
17681768+ if (typeof value === 'object' && value !== null && !(value instanceof Date)) {
17691769+ if ('text' in value) value = (value as { text: string }).text;
17701770+ else if ('hyperlink' in value) value = (value as { hyperlink: string }).hyperlink;
17711771+ else if ('richText' in value) {
17721772+ const parts = (value as { richText: Array<{ text: string }> }).richText;
17731773+ value = Array.isArray(parts) ? parts.map(p => p.text || '').join('') : '';
17741774+ } else {
17751775+ value = JSON.stringify(value);
17761776+ }
17771777+ }
17781778+17671779 if (!format || format === 'auto') {
17681780 if (typeof value === 'number') {
17691781 return Number.isInteger(value) ? value.toString() : value.toFixed(2);
+7-1
src/sheets/main.ts
···654654 cell = new Y.Map();
655655 cells.set(id, cell);
656656 }
657657- // Date objects don't survive Yjs serialization — store as timestamp
657657+ // Ensure only primitives are stored — objects cause [object Object] display
658658 let v = data.v;
659659 if (v instanceof Date) v = v.getTime();
660660+ else if (typeof v === 'object' && v !== null) {
661661+ if ('text' in v) v = v.text;
662662+ else if ('hyperlink' in v) v = v.hyperlink;
663663+ else if ('richText' in v && Array.isArray(v.richText)) v = v.richText.map((p: { text?: string }) => p.text || '').join('');
664664+ else v = String(v);
665665+ }
660666 if (v !== undefined) cell.set('v', v);
661667 if (data.f !== undefined) cell.set('f', data.f);
662668 if (data.s !== undefined) cell.set('s', JSON.stringify(data.s));
+10
src/sheets/xlsx-import.ts
···219219 // Store dates as numeric timestamps — Date objects don't survive Yjs serialization
220220 data.v = cell.value.getTime();
221221 if (!data.s.format) data.s.format = 'date';
222222+ } else if (typeof cell.value === 'object' && cell.value !== null && 'hyperlink' in cell.value) {
223223+ // ExcelJS hyperlink cells: { text: 'Label', hyperlink: 'https://...' }
224224+ data.v = (cell.value as { text?: string; hyperlink: string }).text || (cell.value as { hyperlink: string }).hyperlink;
225225+ } else if (typeof cell.value === 'object' && cell.value !== null && 'richText' in cell.value) {
226226+ // ExcelJS rich text cells: { richText: [{ text: '...' }, ...] }
227227+ const parts = (cell.value as { richText: Array<{ text: string }> }).richText;
228228+ data.v = Array.isArray(parts) ? parts.map(p => p.text || '').join('') : '';
229229+ } else if (typeof cell.value === 'object') {
230230+ // Any other object — coerce to string to prevent [object Object]
231231+ data.v = String(cell.value);
222232 } else {
223233 data.v = cell.value;
224234 }