@a3s-lab/office 0.37.3 → 0.37.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/5416.js CHANGED
@@ -591,6 +591,10 @@ function validateWorkOfficeSpreadsheetContent(content) {
591
591
  type: 'spreadsheet',
592
592
  sheets
593
593
  };
594
+ if (void 0 !== content.dateSystem) {
595
+ if ('1900' !== content.dateSystem && '1904' !== content.dateSystem) invalidWorkOfficeSpreadsheetInput("a Spreadsheet date system of '1900' or '1904'");
596
+ result.dateSystem = content.dateSystem;
597
+ }
594
598
  copyOptionalJsonField(content, result, 'calculation', 'calculation settings');
595
599
  if (void 0 !== content.namedRanges) result.namedRanges = validateIdRecords(content.namedRanges, 'named range');
596
600
  copyOptionalSheetSidecars(content, result, 'printAreas', 'print area');
@@ -1209,6 +1213,7 @@ function claimLabel(claim) {
1209
1213
  return `${claim.kind} in sheet '${claim.parentId}'`;
1210
1214
  }
1211
1215
  function assertWorkOfficeSpreadsheetPatchSafe(previous, next, shared) {
1216
+ assertCompatibleValue(previous.dateSystem, next.dateSystem, shared.dateSystem, 'date system');
1212
1217
  assertCompatibleValue(previous.calculation, next.calculation, shared.calculation, 'calculation settings');
1213
1218
  assertRecordCollection(previous.sheets, next.sheets, shared.sheets, (sheet)=>sheet.id, 'sheet', assertCompatibleSheet);
1214
1219
  assertRecordCollection(previous.namedRanges ?? [], next.namedRanges ?? [], shared.namedRanges ?? [], (range)=>range.id, 'named range');
@@ -1843,7 +1848,7 @@ function workOfficeSpreadsheetRoots(document, rootName) {
1843
1848
  }
1844
1849
  function initializeWorkOfficeSpreadsheetRoots(roots, content) {
1845
1850
  appendWorkOfficeSpreadsheetRecordClaims(roots.recordClaims, void 0, content);
1846
- patchSpreadsheetFlatJsonMap(roots.options, void 0, content.calculation, 'calculation settings');
1851
+ patchSpreadsheetFlatJsonMap(roots.options, void 0, spreadsheetWorkbookOptions(content), 'workbook options');
1847
1852
  patchSheets(roots, void 0, content);
1848
1853
  patchIdRecords(roots.namedRanges, roots.namedRangeOrder, [], content.namedRanges ?? [], 'named range');
1849
1854
  patchSheetSidecars(roots.printAreas, [], content.printAreas ?? [], 'print area');
@@ -1856,7 +1861,9 @@ function readWorkOfficeSpreadsheetRoots(roots) {
1856
1861
  type: 'spreadsheet',
1857
1862
  sheets: validatedSpreadsheetOrder(roots.sheetOrder, roots.sheets, 'sheet').map((id)=>readSpreadsheetSheetRecord(office_spreadsheet_collaboration_records_requiredSpreadsheetMap(roots.sheets, id, `sheet '${id}'`), id))
1858
1863
  };
1859
- const calculation = readSpreadsheetFlatJsonMap(roots.options, 'calculation settings');
1864
+ const options = readSpreadsheetFlatJsonMap(roots.options, 'workbook options');
1865
+ const { dateSystem, ...calculation } = options;
1866
+ if (void 0 !== dateSystem) result.dateSystem = dateSystem;
1860
1867
  if (Object.keys(calculation).length > 0) result.calculation = calculation;
1861
1868
  const namedRanges = readIdRecords(roots.namedRanges, roots.namedRangeOrder, 'named range');
1862
1869
  if (namedRanges.length > 0) result.namedRanges = namedRanges;
@@ -1872,7 +1879,7 @@ function patchWorkOfficeSpreadsheetRoots(roots, previous, next) {
1872
1879
  const shared = readWorkOfficeSpreadsheetRoots(roots);
1873
1880
  assertWorkOfficeSpreadsheetPatchSafe(previous, next, shared);
1874
1881
  appendWorkOfficeSpreadsheetRecordClaims(roots.recordClaims, previous, next);
1875
- patchSpreadsheetFlatJsonMap(roots.options, previous.calculation, next.calculation, 'calculation settings');
1882
+ patchSpreadsheetFlatJsonMap(roots.options, spreadsheetWorkbookOptions(previous), spreadsheetWorkbookOptions(next), 'workbook options');
1876
1883
  patchSheets(roots, previous, next);
1877
1884
  patchIdRecords(roots.namedRanges, roots.namedRangeOrder, previous.namedRanges ?? [], next.namedRanges ?? [], 'named range');
1878
1885
  patchSheetSidecars(roots.printAreas, previous.printAreas ?? [], next.printAreas ?? [], 'print area');
@@ -1880,6 +1887,13 @@ function patchWorkOfficeSpreadsheetRoots(roots, previous, next) {
1880
1887
  patchSheetSidecars(roots.pageBreaks, previous.pageBreaks ?? [], next.pageBreaks ?? [], 'page breaks');
1881
1888
  patchSheetSidecars(roots.pageSetups, previous.pageSetups ?? [], next.pageSetups ?? [], 'page setup');
1882
1889
  }
1890
+ function spreadsheetWorkbookOptions(content) {
1891
+ const options = {
1892
+ ...content.calculation
1893
+ };
1894
+ if (void 0 !== content.dateSystem) options.dateSystem = content.dateSystem;
1895
+ return Object.keys(options).length ? options : void 0;
1896
+ }
1883
1897
  function assertWorkOfficeSpreadsheetRootsEmpty(roots) {
1884
1898
  if (roots.options.size > 0 || roots.sheets.size > 0 || roots.sheetOrder.length > 0 || roots.namedRanges.size > 0 || roots.namedRangeOrder.length > 0 || roots.recordClaims.length > 0 || roots.printAreas.size > 0 || roots.printTitles.size > 0 || roots.pageBreaks.size > 0 || roots.pageSetups.size > 0) throw new WorkOfficeCollaborationError('office.collaboration.bootstrap_ambiguous', 'The Spreadsheet collaboration roots contain data without initialized metadata.');
1885
1899
  }
@@ -2212,9 +2226,8 @@ function workSpreadsheetFilterTextIsBounded(value) {
2212
2226
  return characters >= 1 && characters <= WORK_SPREADSHEET_FILTER_TEXT_MAX_CHARACTERS;
2213
2227
  }
2214
2228
  const MILLISECONDS_PER_DAY = 86400000;
2215
- const EXCEL_1900_EPOCH_UTC = Date.UTC(1899, 11, 30);
2216
2229
  const EXCEL_1900_CIVIL_EPOCH_UTC = Date.UTC(1899, 11, 31);
2217
- const EXCEL_1900_LOCAL_BASE = new Date(1899, 11, 30);
2230
+ const EXCEL_1904_EPOCH_UTC = Date.UTC(1904, 0, 1);
2218
2231
  const SERIAL_INTEGER_EPSILON = 1e-7;
2219
2232
  const CALENDAR_MONTH_FILTERS = [
2220
2233
  'month-1',
@@ -2239,18 +2252,18 @@ const CALENDAR_QUARTER_FILTERS = [
2239
2252
  function workSpreadsheetDynamicFilterMatcher(kind, cells, context) {
2240
2253
  if ('above-average' === kind || 'below-average' === kind) return averageMatcher(kind, cells);
2241
2254
  const month = CALENDAR_MONTH_FILTERS.indexOf(kind);
2242
- if (month >= 0) return (cell)=>spreadsheetDateParts(cell)?.month === month;
2255
+ if (month >= 0) return (cell)=>spreadsheetDateParts(cell, context.dateSystem)?.month === month;
2243
2256
  const quarter = CALENDAR_QUARTER_FILTERS.indexOf(kind);
2244
- if (quarter >= 0) return (cell)=>spreadsheetDateParts(cell)?.quarter === quarter;
2257
+ if (quarter >= 0) return (cell)=>spreadsheetDateParts(cell, context.dateSystem)?.quarter === quarter;
2245
2258
  const bounds = relativeDateBounds(kind, context.now);
2246
2259
  if (!bounds) return null;
2247
2260
  return (cell)=>{
2248
- const day = spreadsheetDateSerialDay(cell);
2261
+ const day = spreadsheetDateCivilDay(cell, context.dateSystem);
2249
2262
  return null !== day && day >= bounds.start && day < bounds.end;
2250
2263
  };
2251
2264
  }
2252
- function workSpreadsheetCellIsDate(cell) {
2253
- return null !== spreadsheetDateSerialDay(cell);
2265
+ function workSpreadsheetCellIsDate(cell, dateSystem = '1900') {
2266
+ return null !== spreadsheetDateCivilDay(cell, dateSystem);
2254
2267
  }
2255
2268
  function averageMatcher(kind, cells) {
2256
2269
  const average = finiteArithmeticMean(cells);
@@ -2284,7 +2297,7 @@ function relativeDateBounds(kind, now) {
2284
2297
  const year = now.getFullYear();
2285
2298
  if (!Number.isFinite(timestamp) || !Number.isSafeInteger(year) || year < 1900 || year > 9999) return null;
2286
2299
  const month = now.getMonth();
2287
- const today = excelSerialFromCivilDate(year, month, now.getDate());
2300
+ const today = civilDayFromDateParts(year, month, now.getDate());
2288
2301
  if ('yesterday' === kind) return dayBounds(today - 1);
2289
2302
  if ('today' === kind) return dayBounds(today);
2290
2303
  if ('tomorrow' === kind) return dayBounds(today + 1);
@@ -2292,65 +2305,64 @@ function relativeDateBounds(kind, now) {
2292
2305
  if ('last-week' === kind) return rangeBounds(weekStart - 7, weekStart);
2293
2306
  if ('this-week' === kind) return rangeBounds(weekStart, weekStart + 7);
2294
2307
  if ('next-week' === kind) return rangeBounds(weekStart + 7, weekStart + 14);
2295
- const monthStart = excelSerialFromCivilDate(year, month, 1);
2296
- if ('last-month' === kind) return rangeBounds(excelSerialFromCivilDate(year, month - 1, 1), monthStart);
2297
- if ('this-month' === kind) return rangeBounds(monthStart, excelSerialFromCivilDate(year, month + 1, 1));
2298
- if ('next-month' === kind) return rangeBounds(excelSerialFromCivilDate(year, month + 1, 1), excelSerialFromCivilDate(year, month + 2, 1));
2308
+ const monthStart = civilDayFromDateParts(year, month, 1);
2309
+ if ('last-month' === kind) return rangeBounds(civilDayFromDateParts(year, month - 1, 1), monthStart);
2310
+ if ('this-month' === kind) return rangeBounds(monthStart, civilDayFromDateParts(year, month + 1, 1));
2311
+ if ('next-month' === kind) return rangeBounds(civilDayFromDateParts(year, month + 1, 1), civilDayFromDateParts(year, month + 2, 1));
2299
2312
  const quarterStartMonth = 3 * Math.floor(month / 3);
2300
- const quarterStart = excelSerialFromCivilDate(year, quarterStartMonth, 1);
2301
- if ('last-quarter' === kind) return rangeBounds(excelSerialFromCivilDate(year, quarterStartMonth - 3, 1), quarterStart);
2302
- if ('this-quarter' === kind) return rangeBounds(quarterStart, excelSerialFromCivilDate(year, quarterStartMonth + 3, 1));
2303
- if ('next-quarter' === kind) return rangeBounds(excelSerialFromCivilDate(year, quarterStartMonth + 3, 1), excelSerialFromCivilDate(year, quarterStartMonth + 6, 1));
2304
- const yearStart = excelSerialFromCivilDate(year, 0, 1);
2305
- if ('last-year' === kind) return rangeBounds(excelSerialFromCivilDate(year - 1, 0, 1), yearStart);
2306
- if ('this-year' === kind) return rangeBounds(yearStart, excelSerialFromCivilDate(year + 1, 0, 1));
2307
- if ('next-year' === kind) return rangeBounds(excelSerialFromCivilDate(year + 1, 0, 1), excelSerialFromCivilDate(year + 2, 0, 1));
2313
+ const quarterStart = civilDayFromDateParts(year, quarterStartMonth, 1);
2314
+ if ('last-quarter' === kind) return rangeBounds(civilDayFromDateParts(year, quarterStartMonth - 3, 1), quarterStart);
2315
+ if ('this-quarter' === kind) return rangeBounds(quarterStart, civilDayFromDateParts(year, quarterStartMonth + 3, 1));
2316
+ if ('next-quarter' === kind) return rangeBounds(civilDayFromDateParts(year, quarterStartMonth + 3, 1), civilDayFromDateParts(year, quarterStartMonth + 6, 1));
2317
+ const yearStart = civilDayFromDateParts(year, 0, 1);
2318
+ if ('last-year' === kind) return rangeBounds(civilDayFromDateParts(year - 1, 0, 1), yearStart);
2319
+ if ('this-year' === kind) return rangeBounds(yearStart, civilDayFromDateParts(year + 1, 0, 1));
2320
+ if ('next-year' === kind) return rangeBounds(civilDayFromDateParts(year + 1, 0, 1), civilDayFromDateParts(year + 2, 0, 1));
2308
2321
  if ('year-to-date' === kind) return rangeBounds(yearStart, today + 1);
2309
2322
  return null;
2310
2323
  }
2311
- function spreadsheetDateParts(cell) {
2312
- const day = spreadsheetDateSerialDay(cell);
2324
+ function spreadsheetDateParts(cell, dateSystem = '1900') {
2325
+ const day = spreadsheetDateCivilDay(cell, dateSystem);
2313
2326
  if (null === day) return null;
2314
- const adjustedDay = day > 60 ? day - 1 : day;
2315
- const date = new Date(EXCEL_1900_CIVIL_EPOCH_UTC + adjustedDay * MILLISECONDS_PER_DAY);
2327
+ const date = new Date(day * MILLISECONDS_PER_DAY);
2316
2328
  const timestamp = date.getTime();
2317
2329
  const year = date.getUTCFullYear();
2318
- if (!Number.isFinite(timestamp) || year < 1900 || year > 9999) return null;
2330
+ if (!Number.isFinite(timestamp) || year > 9999) return null;
2319
2331
  const month = date.getUTCMonth();
2320
2332
  return {
2321
2333
  month,
2322
2334
  quarter: Math.floor(month / 3)
2323
2335
  };
2324
2336
  }
2325
- function spreadsheetDateSerialDay(cell) {
2326
- const serial = spreadsheetDateCellSerial(cell);
2327
- if (null === serial) return null;
2328
- const rounded = Math.round(serial);
2329
- const normalized = Math.abs(serial - rounded) <= SERIAL_INTEGER_EPSILON ? rounded : serial;
2330
- const day = Math.floor(normalized);
2331
- return day >= 1 && 60 !== day ? day : null;
2332
- }
2333
- function spreadsheetDateCellSerial(cell) {
2337
+ function spreadsheetDateCivilDay(cell, dateSystem = '1900') {
2334
2338
  const value = spreadsheetCellRawValue(cell);
2335
2339
  if (value instanceof Date) {
2336
2340
  if (!Number.isFinite(value.getTime())) return null;
2337
- const threshold = EXCEL_1900_LOCAL_BASE.getTime() + (value.getTimezoneOffset() - EXCEL_1900_LOCAL_BASE.getTimezoneOffset()) * 60000;
2338
- const serial = (value.getTime() - threshold) / MILLISECONDS_PER_DAY;
2339
- return Number.isFinite(serial) ? serial : null;
2341
+ const year = value.getFullYear();
2342
+ const minimumYear = '1904' === dateSystem ? 1904 : 1900;
2343
+ return year >= minimumYear && year <= 9999 ? civilDayFromDateParts(year, value.getMonth(), value.getDate()) : null;
2340
2344
  }
2341
- return 'number' == typeof value && Number.isFinite(value) && cell?.ct?.t === 'd' ? value : null;
2345
+ if ('number' != typeof value || !Number.isFinite(value) || cell?.ct?.t !== 'd') return null;
2346
+ const serial = value;
2347
+ const rounded = Math.round(serial);
2348
+ const normalized = Math.abs(serial - rounded) <= SERIAL_INTEGER_EPSILON ? rounded : serial;
2349
+ const day = Math.floor(normalized);
2350
+ if ('1904' === dateSystem) return day >= 0 ? (EXCEL_1904_EPOCH_UTC + day * MILLISECONDS_PER_DAY) / MILLISECONDS_PER_DAY : null;
2351
+ if (day < 1 || 60 === day) return null;
2352
+ const civilOffset = day > 60 ? day - 1 : day;
2353
+ return (EXCEL_1900_CIVIL_EPOCH_UTC + civilOffset * MILLISECONDS_PER_DAY) / MILLISECONDS_PER_DAY;
2342
2354
  }
2343
2355
  function spreadsheetNumericCellValue(cell) {
2344
- if (null !== spreadsheetDateCellSerial(cell)) return null;
2345
2356
  const value = spreadsheetCellRawValue(cell);
2357
+ if (value instanceof Date || cell?.ct?.t === 'd') return null;
2346
2358
  return 'number' == typeof value && Number.isFinite(value) ? value : null;
2347
2359
  }
2348
2360
  function spreadsheetCellRawValue(cell) {
2349
2361
  const candidate = cell;
2350
2362
  return candidate?.v ?? candidate?.m;
2351
2363
  }
2352
- function excelSerialFromCivilDate(year, month, day) {
2353
- return (Date.UTC(year, month, day) - EXCEL_1900_EPOCH_UTC) / MILLISECONDS_PER_DAY;
2364
+ function civilDayFromDateParts(year, month, day) {
2365
+ return Date.UTC(year, month, day) / MILLISECONDS_PER_DAY;
2354
2366
  }
2355
2367
  function dayBounds(day) {
2356
2368
  return {
@@ -2756,6 +2768,33 @@ function workSpreadsheetAutoFilterManuallyHiddenRows(sheet) {
2756
2768
  }
2757
2769
  return manuallyHidden;
2758
2770
  }
2771
+ function workSpreadsheetAutoFilterOwnedRows(sheet) {
2772
+ return filterHiddenRows(sheet.filter);
2773
+ }
2774
+ function workSpreadsheetFilterHiddenRows(sheet, range, column, criteria, context = {
2775
+ now: new Date()
2776
+ }) {
2777
+ const normalizedCriteria = normalizeWorkSpreadsheetFilterCriteria(criteria);
2778
+ const normalizedRange = normalizedWorkSpreadsheetAutoFilterRange(range);
2779
+ if (!normalizedCriteria || !normalizedRange || !columnInRange(normalizedRange, column)) return null;
2780
+ return hiddenRowsForCriteria(sheet, normalizedRange, column, normalizedCriteria, context);
2781
+ }
2782
+ function workSpreadsheetSheetWithReappliedAutoFilterCriteria(sheet, criteriaSource, manuallyHiddenRows, context = {
2783
+ now: new Date()
2784
+ }) {
2785
+ const range = normalizedWorkSpreadsheetAutoFilterRange(sheet.filter_select);
2786
+ if (!range) return sheet;
2787
+ const entries = workSpreadsheetAutoFilterCriteriaEntries(criteriaSource);
2788
+ const filter = {};
2789
+ for (const entry of entries){
2790
+ const column = range.column[0] + entry.column;
2791
+ const criteria = normalizeWorkSpreadsheetFilterCriteria(entry.criteria);
2792
+ if (!criteria || !columnInRange(range, column)) continue;
2793
+ const rowhidden = hiddenRowsForCriteria(sheet, range, column, criteria, context);
2794
+ if (rowhidden) filter[String(entry.column)] = filterColumnState(range, column, criteria, rowhidden);
2795
+ }
2796
+ return sheetWithFilterState(sheet, filter, manuallyHiddenRows);
2797
+ }
2759
2798
  function workSpreadsheetSheetWithImportedAutoFilterCriteria(sheet, entries, context = {
2760
2799
  now: new Date()
2761
2800
  }) {
@@ -4047,4 +4086,4 @@ function normalizeStoredSpreadsheetSortCustomLists(input) {
4047
4086
  function spreadsheet_sort_custom_list_store_isRecord(value) {
4048
4087
  return Boolean(value && 'object' == typeof value && !Array.isArray(value));
4049
4088
  }
4050
- export { DEFAULT_SPREADSHEET_SORT_CUSTOM_LIST_STORAGE_KEY, LocalStorageSpreadsheetSortCustomListStore, SPREADSHEET_TABLE_TOTALS_FUNCTIONS, activeXlsxNativeFill, activeXlsxSemanticColorOrigin, applyImportedXlsxRichText, boundedSpreadsheetDataValidationText, coalesceXlsxRichTextRuns, createSpreadsheetSortCustomList, createWorkOfficeSpreadsheetCollaborationBinding as createOfficeSpreadsheetCollaborationBinding, createXlsxRichTextReadContext, deleteXlsxNativeFills, directXlsxAlignment, directXlsxFontStyle, fillSpreadsheetTableCalculatedColumns, hasXlsxDirectFontStyle, initializeWorkOfficeSpreadsheetCollaboration as initializeOfficeSpreadsheetCollaboration, isHighSurrogate, isLowSurrogate, isSpreadsheetTextOrientationId, isSpreadsheetUnderlineStyle, mergeSpreadsheetSortCustomLists, normalizeSpreadsheetDataValidationErrorStyle, normalizeSpreadsheetDateValidationBoundary, normalizeSpreadsheetTableCalculatedFormula, normalizeSpreadsheetTableTotalsFormula, normalizeSpreadsheetTableTotalsLabel, normalizeStoredSpreadsheetSortCustomLists, normalizeWorkSpreadsheetFilterCriteria, normalizeXlsxRichTextCell, normalizeXlsxRichTextColor, normalizeXlsxRichTextEditSource, normalizeXlsxRichTextRun, normalizedWorkSpreadsheetAutoFilterRange, parseSpreadsheetSortCustomList, patchSpreadsheetRichTextFontRuns, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, readXlsxRichTextCells, reconcileSpreadsheetTableCalculatedColumns, reconcileSpreadsheetTableTotalsColumns, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, sameXlsxRichTextRunStyle, sheetHasXlsxRichTextCells, spreadsheetCellValueWithDiagonalBorder, spreadsheetDateValidationFormula, spreadsheetDiagonalBorderFromCellValue, spreadsheetExplicitTextOrientationFromCell, spreadsheetSortCustomListMatchKey, spreadsheetSortCustomListsEqual, spreadsheetTableTotalsColumnPatch, spreadsheetTableTotalsFunctionFromOoxml, spreadsheetTableTotalsFunctionLabel, spreadsheetTableTotalsFunctionToOoxml, spreadsheetTableTotalsRowHasContent, spreadsheetTextOrientationCellStyle, spreadsheetTextOrientationChoiceFromCell, spreadsheetTextOrientationFromAngle, spreadsheetTextOrientationFromCell, spreadsheetTextOrientationFromChoice, spreadsheetTextOrientationFromXlsx, spreadsheetUnderlineCellValue, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetUnderlineCellValueFromXlsx, spreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell, synchronizeSpreadsheetTableTotalsRow, validXlsxRichText, validateSpreadsheetSortCustomList, withDefaultSpreadsheetTableTotalsLabel, workSpreadsheetAutoFilterCriteria, workSpreadsheetAutoFilterCriteriaEntries, workSpreadsheetAutoFilterManuallyHiddenRows, workSpreadsheetCellIsDate, workSpreadsheetFilterTextCharacters, workSpreadsheetHasUnescapedWildcard, workSpreadsheetSheetWithAutoFilterCriteria, workSpreadsheetSheetWithImportedAutoFilterCriteria, workSpreadsheetSheetWithoutAutoFilterCriteria, writeXlsxRichTextCells, xlsxAlignmentMatches, xlsxBooleanAttribute, xlsxBorderLineMatches, xlsxColorMatches, xlsxNativeFillCellKeys, xlsxNativeFillKey, xlsxNativeFillSemanticColors, xlsxRichTextCellText, xlsxRichTextStyleOrigins, xlsxStyleCollectionIndex, xlsxToggleEnabled, xlsxUnderlineStyle };
4089
+ export { DEFAULT_SPREADSHEET_SORT_CUSTOM_LIST_STORAGE_KEY, LocalStorageSpreadsheetSortCustomListStore, SPREADSHEET_TABLE_TOTALS_FUNCTIONS, activeXlsxNativeFill, activeXlsxSemanticColorOrigin, applyImportedXlsxRichText, boundedSpreadsheetDataValidationText, coalesceXlsxRichTextRuns, createSpreadsheetSortCustomList, createWorkOfficeSpreadsheetCollaborationBinding as createOfficeSpreadsheetCollaborationBinding, createXlsxRichTextReadContext, deleteXlsxNativeFills, directXlsxAlignment, directXlsxFontStyle, fillSpreadsheetTableCalculatedColumns, hasXlsxDirectFontStyle, initializeWorkOfficeSpreadsheetCollaboration as initializeOfficeSpreadsheetCollaboration, isHighSurrogate, isLowSurrogate, isSpreadsheetTextOrientationId, isSpreadsheetUnderlineStyle, mergeSpreadsheetSortCustomLists, normalizeSpreadsheetDataValidationErrorStyle, normalizeSpreadsheetDateValidationBoundary, normalizeSpreadsheetTableCalculatedFormula, normalizeSpreadsheetTableTotalsFormula, normalizeSpreadsheetTableTotalsLabel, normalizeStoredSpreadsheetSortCustomLists, normalizeWorkSpreadsheetFilterCriteria, normalizeXlsxRichTextCell, normalizeXlsxRichTextColor, normalizeXlsxRichTextEditSource, normalizeXlsxRichTextRun, normalizedWorkSpreadsheetAutoFilterRange, parseSpreadsheetSortCustomList, patchSpreadsheetRichTextFontRuns, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, readXlsxRichTextCells, reconcileSpreadsheetTableCalculatedColumns, reconcileSpreadsheetTableTotalsColumns, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, sameXlsxRichTextRunStyle, sheetHasXlsxRichTextCells, spreadsheetCellValueWithDiagonalBorder, spreadsheetDateValidationFormula, spreadsheetDiagonalBorderFromCellValue, spreadsheetExplicitTextOrientationFromCell, spreadsheetSortCustomListMatchKey, spreadsheetSortCustomListsEqual, spreadsheetTableTotalsColumnPatch, spreadsheetTableTotalsFunctionFromOoxml, spreadsheetTableTotalsFunctionLabel, spreadsheetTableTotalsFunctionToOoxml, spreadsheetTableTotalsRowHasContent, spreadsheetTextOrientationCellStyle, spreadsheetTextOrientationChoiceFromCell, spreadsheetTextOrientationFromAngle, spreadsheetTextOrientationFromCell, spreadsheetTextOrientationFromChoice, spreadsheetTextOrientationFromXlsx, spreadsheetUnderlineCellValue, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetUnderlineCellValueFromXlsx, spreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell, synchronizeSpreadsheetTableTotalsRow, validXlsxRichText, validateSpreadsheetSortCustomList, withDefaultSpreadsheetTableTotalsLabel, workSpreadsheetAutoFilterCriteria, workSpreadsheetAutoFilterCriteriaEntries, workSpreadsheetAutoFilterManuallyHiddenRows, workSpreadsheetAutoFilterOwnedRows, workSpreadsheetCellIsDate, workSpreadsheetFilterHiddenRows, workSpreadsheetFilterTextCharacters, workSpreadsheetHasUnescapedWildcard, workSpreadsheetSheetWithAutoFilterCriteria, workSpreadsheetSheetWithImportedAutoFilterCriteria, workSpreadsheetSheetWithReappliedAutoFilterCriteria, workSpreadsheetSheetWithoutAutoFilterCriteria, writeXlsxRichTextCells, xlsxAlignmentMatches, xlsxBooleanAttribute, xlsxBorderLineMatches, xlsxColorMatches, xlsxNativeFillCellKeys, xlsxNativeFillKey, xlsxNativeFillSemanticColors, xlsxRichTextCellText, xlsxRichTextStyleOrigins, xlsxStyleCollectionIndex, xlsxToggleEnabled, xlsxUnderlineStyle };
package/dist/core.js CHANGED
@@ -3464,12 +3464,16 @@ async function createWorkSpreadsheetBlob(artifact) {
3464
3464
  const XLSX = await import("xlsx");
3465
3465
  const workbook = XLSX.utils.book_new();
3466
3466
  for (const sheet of content.sheets){
3467
- const worksheet = createSparseXlsxWorksheet(sheet, XLSX);
3467
+ const worksheet = createSparseXlsxWorksheet(sheet, XLSX, content.dateSystem);
3468
3468
  applySpreadsheetLayout(worksheet, sheet);
3469
3469
  XLSX.utils.book_append_sheet(workbook, worksheet, sheet.name.slice(0, 31) || '工作表');
3470
3470
  }
3471
3471
  workbook.Workbook = {
3472
3472
  ...workbook.Workbook,
3473
+ WBProps: {
3474
+ ...workbook.Workbook?.WBProps,
3475
+ date1904: '1904' === content.dateSystem
3476
+ },
3473
3477
  Sheets: content.sheets.map((sheet)=>({
3474
3478
  name: sheet.name.slice(0, 31) || '工作表',
3475
3479
  Hidden: sheet.hide ? 1 : 0
@@ -3492,7 +3496,7 @@ async function createWorkSpreadsheetBlob(artifact) {
3492
3496
  type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
3493
3497
  });
3494
3498
  }
3495
- function createSparseXlsxWorksheet(sheet, XLSX) {
3499
+ function createSparseXlsxWorksheet(sheet, XLSX, dateSystem = '1900') {
3496
3500
  const data = sheet.data ?? [];
3497
3501
  const worksheet = {
3498
3502
  '!a3sSparse': true
@@ -3511,7 +3515,7 @@ function createSparseXlsxWorksheet(sheet, XLSX) {
3511
3515
  const style = xlsxCellStyle(cell);
3512
3516
  const comment = exportXlsxCellComment(cell.ps);
3513
3517
  const hyperlink = sheet.hyperlink?.[`${rowIndex}_${columnIndex}`];
3514
- const target = xlsxCellObject(cell, rowIndex, columnIndex, sheet) ?? (style || comment || hyperlink ? {
3518
+ const target = xlsxCellObject(cell, rowIndex, columnIndex, sheet, dateSystem) ?? (style || comment || hyperlink ? {
3515
3519
  t: 's',
3516
3520
  v: ''
3517
3521
  } : null);
@@ -3538,14 +3542,30 @@ function createSparseXlsxWorksheet(sheet, XLSX) {
3538
3542
  });
3539
3543
  return worksheet;
3540
3544
  }
3541
- function xlsxCellObject(cell, row, column, sheet) {
3542
- if (cell.f) return createXlsxFormulaCell(cell, row, column, sheet);
3545
+ function xlsxCellObject(cell, row, column, sheet, dateSystem) {
3546
+ if (cell.f) {
3547
+ const formula = createXlsxFormulaCell(cell, row, column, sheet);
3548
+ if (formula.v instanceof Date && Number.isFinite(formula.v.getTime())) return {
3549
+ ...formula,
3550
+ t: 'n',
3551
+ v: spreadsheetDateSerial(formula.v, dateSystem)
3552
+ };
3553
+ if ('d' === formula.t && 'number' == typeof formula.v) return {
3554
+ ...formula,
3555
+ t: 'n'
3556
+ };
3557
+ return formula;
3558
+ }
3543
3559
  if (cell.ct?.t === 'e') return createXlsxErrorCell(cell);
3544
3560
  const value = xlsxRichTextCellText(cell) ?? cell.v ?? cell.m;
3545
3561
  if (null == value) return cell.ps ? {
3546
3562
  t: 's',
3547
3563
  v: ''
3548
3564
  } : null;
3565
+ if (value instanceof Date && Number.isFinite(value.getTime())) return {
3566
+ t: 'n',
3567
+ v: spreadsheetDateSerial(value, dateSystem)
3568
+ };
3549
3569
  if ('boolean' == typeof value) return {
3550
3570
  t: 'b',
3551
3571
  v: value
@@ -3559,6 +3579,15 @@ function xlsxCellObject(cell, row, column, sheet) {
3559
3579
  v: String(value)
3560
3580
  };
3561
3581
  }
3582
+ function spreadsheetDateSerial(value, dateSystem) {
3583
+ const year = value.getFullYear();
3584
+ const month = value.getMonth();
3585
+ const day = value.getDate();
3586
+ const time = (3600000 * value.getHours() + 60000 * value.getMinutes() + 1000 * value.getSeconds() + value.getMilliseconds()) / 86400000;
3587
+ if ('1904' === dateSystem) return (Date.UTC(year, month, day) - Date.UTC(1904, 0, 1)) / 86400000 + time;
3588
+ const civilDay = (Date.UTC(year, month, day) - Date.UTC(1899, 11, 31)) / 86400000;
3589
+ return civilDay + (civilDay >= 60 ? 1 : 0) + time;
3590
+ }
3562
3591
  function applySpreadsheetLayout(worksheet, sheet) {
3563
3592
  const merges = Object.values(sheet.config?.merge ?? {});
3564
3593
  if (merges.length) worksheet['!merges'] = merges.map((merge)=>({
@@ -4101,7 +4130,7 @@ async function importWorkSpreadsheetFile(file, extension, context) {
4101
4130
  const initialRequiresCellStyles = archive ? archive.has('xl/styles.xml') : true;
4102
4131
  let readOptions = {
4103
4132
  type: 'array',
4104
- cellDates: true,
4133
+ cellDates: false,
4105
4134
  cellFormula: true,
4106
4135
  cellHTML: false,
4107
4136
  cellStyles: initialRequiresCellStyles,
@@ -4185,6 +4214,11 @@ async function importWorkSpreadsheetFile(file, extension, context) {
4185
4214
  ]);
4186
4215
  const XLSX = usesPlainXlsxFastPath ? null : await loadSheetJs();
4187
4216
  const [sheetFeatures, formulaFeatures, pivotFeatures] = importedFeatures;
4217
+ const dateSystem = workbook.Workbook?.WBProps?.date1904 ? '1904' : '1900';
4218
+ const dynamicFilterContext = {
4219
+ dateSystem,
4220
+ now: new Date()
4221
+ };
4188
4222
  await context.controller.checkpoint('parsing', 0.2);
4189
4223
  await context.controller.checkpoint('parsing', 0.4);
4190
4224
  const conversionStartedAt = spreadsheetImportNow();
@@ -4301,7 +4335,7 @@ async function importWorkSpreadsheetFile(file, extension, context) {
4301
4335
  charts: features?.charts.length ? xlsxWorksheetChartsToSheet(features.charts, config) : void 0,
4302
4336
  tables: features?.tables.length ? features.tables : void 0,
4303
4337
  formulaMetadata
4304
- }, features?.autoFilterCriteria ?? []));
4338
+ }, features?.autoFilterCriteria ?? [], dynamicFilterContext));
4305
4339
  await context.controller.checkpoint('parsing', sheetProgressStart + sheetProgressSize);
4306
4340
  }
4307
4341
  const workbookMetadata = importXlsxDefinedNames(workbook, sheets);
@@ -4330,6 +4364,9 @@ async function importWorkSpreadsheetFile(file, extension, context) {
4330
4364
  artifact.content = applyImportedXlsxPivotTables({
4331
4365
  type: 'spreadsheet',
4332
4366
  sheets,
4367
+ ...'1904' === dateSystem ? {
4368
+ dateSystem
4369
+ } : {},
4333
4370
  calculation: formulaFeatures?.calculation,
4334
4371
  ...workbookMetadata,
4335
4372
  pageBreaks: pageBreaks.length ? pageBreaks : void 0,
@@ -4447,7 +4484,7 @@ function fortuneSheetConfig(worksheet) {
4447
4484
  }
4448
4485
  function fortuneCellFromXlsx(source, row, column, sheetId, hyperlink, comment, XLSX, directStyle) {
4449
4486
  const cell = {
4450
- ...fortuneCellStyle(source),
4487
+ ...fortuneCellStyle(source, XLSX),
4451
4488
  ...directStyle
4452
4489
  };
4453
4490
  const orientation = spreadsheetExplicitTextOrientationFromCell(cell);
@@ -4476,7 +4513,7 @@ function fortuneCellFromXlsx(source, row, column, sheetId, hyperlink, comment, X
4476
4513
  function spreadsheetCellKey(row, column) {
4477
4514
  return `${row}_${column}`;
4478
4515
  }
4479
- function fortuneCellStyle(source) {
4516
+ function fortuneCellStyle(source, XLSX) {
4480
4517
  const style = source.s;
4481
4518
  const font = style && 'object' == typeof style ? style.font : void 0;
4482
4519
  const fill = style && 'object' == typeof style ? style.fill : void 0;
@@ -4504,10 +4541,19 @@ function fortuneCellStyle(source) {
4504
4541
  if (orientationStyle) Object.assign(target, orientationStyle);
4505
4542
  if (source.z && 'General' !== source.z || 'e' === source.t) target.ct = {
4506
4543
  fa: source.z && 'General' !== source.z ? String(source.z) : void 0,
4507
- t: source.t
4544
+ t: xlsxCellIsDate(source, XLSX) ? 'd' : source.t
4508
4545
  };
4509
4546
  return target;
4510
4547
  }
4548
+ function xlsxCellIsDate(source, XLSX) {
4549
+ if ('d' === source.t) return true;
4550
+ if ('n' !== source.t || !source.z || 'General' === source.z) return false;
4551
+ try {
4552
+ return Boolean(XLSX.SSF.is_date(String(source.z)));
4553
+ } catch {
4554
+ return false;
4555
+ }
4556
+ }
4511
4557
  function fortuneCellDisplayText(source, XLSX) {
4512
4558
  if (void 0 !== source.w) return source.w;
4513
4559
  if (void 0 === source.v || null === source.v) return;
@@ -1,6 +1,6 @@
1
- import type { WorkSpreadsheetSheet } from '../work-types';
1
+ import type { WorkSpreadsheetDateSystem, WorkSpreadsheetSheet } from '../work-types';
2
2
  export declare const SPREADSHEET_AUTO_FILTER_MENU_ITEMS: string[];
3
- export declare function enhanceSpreadsheetAutoFilterSurface(container: HTMLElement, sheet: WorkSpreadsheetSheet | undefined, invoker: HTMLElement | null): HTMLElement | null;
3
+ export declare function enhanceSpreadsheetAutoFilterSurface(container: HTMLElement, sheet: WorkSpreadsheetSheet | undefined, invoker: HTMLElement | null, dateSystem?: WorkSpreadsheetDateSystem): HTMLElement | null;
4
4
  export declare function focusSpreadsheetAutoFilterMenu(container: HTMLElement): void;
5
5
  export declare function spreadsheetAutoFilterMenuFocusable(menu: HTMLElement): HTMLElement[];
6
6
  export declare function spreadsheetAutoFilterTrigger(target: EventTarget | null): HTMLElement | null;
@@ -1,5 +1,5 @@
1
1
  import type { Selection } from '@fortune-sheet/core';
2
- import type { WorkSpreadsheetFilterCriteria, WorkSpreadsheetContent, WorkSpreadsheetSheet } from '../work-types';
2
+ import type { WorkSpreadsheetDateSystem, WorkSpreadsheetFilterCriteria, WorkSpreadsheetContent, WorkSpreadsheetSheet } from '../work-types';
3
3
  import { type WorkSpreadsheetAutoFilterRange } from '../work-spreadsheet-auto-filter';
4
4
  import { type WorkSpreadsheetDynamicFilterContext } from '../work-spreadsheet-dynamic-filter';
5
5
  export type SpreadsheetAutoFilterRange = WorkSpreadsheetAutoFilterRange;
@@ -16,7 +16,7 @@ export declare function spreadsheetSelectionOrCurrentRegion(sheet: WorkSpreadshe
16
16
  export declare function spreadsheetAutoFilterHeaderColumn(sheet: WorkSpreadsheetSheet | undefined, selection: Selection): number | null;
17
17
  export declare function toggleSpreadsheetAutoFilter(content: WorkSpreadsheetContent, sheetId: string, selection: Selection): WorkSpreadsheetContent | null;
18
18
  export declare function spreadsheetAutoFilterCriteria(sheet: WorkSpreadsheetSheet | undefined, column: number): WorkSpreadsheetFilterCriteria | null;
19
- export declare function spreadsheetAutoFilterColumnIsNumeric(sheet: WorkSpreadsheetSheet, range: SpreadsheetAutoFilterRange, column: number): boolean;
20
- export declare function spreadsheetAutoFilterColumnIsDate(sheet: WorkSpreadsheetSheet, range: SpreadsheetAutoFilterRange, column: number): boolean;
19
+ export declare function spreadsheetAutoFilterColumnIsNumeric(sheet: WorkSpreadsheetSheet, range: SpreadsheetAutoFilterRange, column: number, dateSystem?: WorkSpreadsheetDateSystem): boolean;
20
+ export declare function spreadsheetAutoFilterColumnIsDate(sheet: WorkSpreadsheetSheet, range: SpreadsheetAutoFilterRange, column: number, dateSystem?: WorkSpreadsheetDateSystem): boolean;
21
21
  export declare function applySpreadsheetAutoFilterCriteria(content: WorkSpreadsheetContent, sheetId: string, column: number, criteria: WorkSpreadsheetFilterCriteria, context?: WorkSpreadsheetDynamicFilterContext): WorkSpreadsheetContent | null;
22
22
  export declare function clearSpreadsheetAutoFilterCriteria(content: WorkSpreadsheetContent, sheetId: string, column: number): WorkSpreadsheetContent | null;
@@ -1,4 +1,5 @@
1
1
  import type { Cell } from '@fortune-sheet/core';
2
+ import type { WorkSpreadsheetDateSystem } from '../work-types';
2
3
  import type { SpreadsheetCommandContext, SpreadsheetEditorCommands } from './spreadsheet-command-controller';
3
4
  import { type OfficeEditorExtension } from './office-editor-extension';
4
5
  export type SpreadsheetDateTimeKind = 'date' | 'time';
@@ -10,5 +11,5 @@ export interface SpreadsheetDateTimeEntry {
10
11
  formulaBarValue: string;
11
12
  value: number;
12
13
  }
13
- export declare function spreadsheetDateTimeEntry(kind: SpreadsheetDateTimeKind, now: Date): SpreadsheetDateTimeEntry | null;
14
+ export declare function spreadsheetDateTimeEntry(kind: SpreadsheetDateTimeKind, now: Date, dateSystem?: WorkSpreadsheetDateSystem): SpreadsheetDateTimeEntry | null;
14
15
  export declare function createSpreadsheetDateTimeExtension(): OfficeEditorExtension<SpreadsheetCommandContext, SpreadsheetEditorCommands>;
@@ -1,5 +1,5 @@
1
1
  import type { Cell, Op, Selection } from '@fortune-sheet/core';
2
- import type { WorkSpreadsheetContent } from '../work-types';
2
+ import type { WorkSpreadsheetContent, WorkSpreadsheetDateSystem } from '../work-types';
3
3
  import type { OfficeSelectOption } from './office-select';
4
4
  export interface SpreadsheetSelectionSummary {
5
5
  average: number | null;
@@ -21,7 +21,7 @@ export declare function spreadsheetFontSizeOptions(current: number | undefined):
21
21
  export declare function spreadsheetFontFamilyOptions(current: string | undefined): OfficeSelectOption[];
22
22
  export declare function spreadsheetSheetsWithFiniteSelections(sheets: WorkSpreadsheetContent['sheets']): WorkSpreadsheetContent['sheets'];
23
23
  export declare function spreadsheetSheetsForFortune(sheets: WorkSpreadsheetContent['sheets']): WorkSpreadsheetContent['sheets'];
24
- export declare function spreadsheetSheetsFromFortune(sheets: WorkSpreadsheetContent['sheets'], sourceSheets: WorkSpreadsheetContent['sheets'], operations?: readonly Op[]): WorkSpreadsheetContent['sheets'];
24
+ export declare function spreadsheetSheetsFromFortune(sheets: WorkSpreadsheetContent['sheets'], sourceSheets: WorkSpreadsheetContent['sheets'], operations?: readonly Op[], dateSystem?: WorkSpreadsheetDateSystem): WorkSpreadsheetContent['sheets'];
25
25
  export declare function finiteSpreadsheetSelection(selection: Selection | undefined): Selection;
26
26
  export declare function sameSpreadsheetWorkbookState(changed: WorkSpreadsheetContent['sheets'], rendered: WorkSpreadsheetContent['sheets']): boolean;
27
27
  /**
@@ -0,0 +1,7 @@
1
+ import type { Op } from '@fortune-sheet/core';
2
+ import type { WorkSpreadsheetDynamicFilterContext } from '../work-spreadsheet-dynamic-filter';
3
+ import type { WorkSpreadsheetContent, WorkSpreadsheetSheet } from '../work-types';
4
+ import type { SpreadsheetCellRange } from './spreadsheet-cell-range';
5
+ export declare function reconcileSpreadsheetFiltersAfterFortune(sheets: WorkSpreadsheetContent['sheets'], sourceSheets: WorkSpreadsheetContent['sheets'], operations?: readonly Op[], context?: WorkSpreadsheetDynamicFilterContext): WorkSpreadsheetContent['sheets'];
6
+ export declare function reconcileSpreadsheetFiltersAfterSort(sheet: WorkSpreadsheetSheet, source: WorkSpreadsheetSheet, range: SpreadsheetCellRange, sourceIndexes: readonly number[], context?: WorkSpreadsheetDynamicFilterContext): WorkSpreadsheetSheet | null;
7
+ export declare function spreadsheetFilterReconciliationIsBounded(sheet: WorkSpreadsheetSheet): boolean;
@@ -1,6 +1,7 @@
1
1
  import type { SpreadsheetSortOptions } from './spreadsheet-sort';
2
- export declare function SpreadsheetSortOptionsDialog({ value, restoreFocusTarget, onApply, onClose, }: {
2
+ export declare function SpreadsheetSortOptionsDialog({ value, orientationLocked, restoreFocusTarget, onApply, onClose, }: {
3
3
  value: SpreadsheetSortOptions;
4
+ orientationLocked?: boolean;
4
5
  restoreFocusTarget: () => HTMLElement | null;
5
6
  onApply: (value: SpreadsheetSortOptions) => void;
6
7
  onClose: () => void;
@@ -55,10 +55,24 @@ export interface SpreadsheetSortTarget {
55
55
  activeColumn: number;
56
56
  activeRow: number;
57
57
  range: SpreadsheetCellRange;
58
+ scope?: SpreadsheetSortOwnedScope;
59
+ }
60
+ export type SpreadsheetSortOwnedScope = {
61
+ hasHeader: true;
62
+ kind: 'auto-filter';
63
+ } | {
64
+ hasHeader: boolean;
65
+ kind: 'table';
66
+ tableId: string;
67
+ };
68
+ export interface SpreadsheetSortOwnedRange {
69
+ range: SpreadsheetCellRange;
70
+ scope: SpreadsheetSortOwnedScope;
58
71
  }
59
72
  export interface SpreadsheetSortRangeCandidate {
60
73
  available: boolean;
61
74
  range: SpreadsheetCellRange;
75
+ scope?: SpreadsheetSortOwnedScope;
62
76
  }
63
77
  export type SpreadsheetSortIntent = {
64
78
  type: 'custom';
@@ -83,15 +97,18 @@ export interface SpreadsheetSortRangeDialogSource {
83
97
  canSortExpandedRange: boolean;
84
98
  canSortSelection: boolean;
85
99
  expandedRangeReference: string;
100
+ ownedScope?: SpreadsheetSortOwnedScope;
86
101
  selectedRangeReference: string;
87
102
  sheetName: string;
88
103
  }
89
104
  export type SpreadsheetSortRequest = Omit<SpreadsheetSortDialogValue, keyof SpreadsheetSortTextOptions> & Partial<SpreadsheetSortTextOptions> & {
90
105
  range: SpreadsheetCellRange;
106
+ scope?: SpreadsheetSortOwnedScope;
91
107
  sheetId: string;
92
108
  };
93
109
  export interface SpreadsheetSortNormalizedRequest extends SpreadsheetSortDialogValue {
94
110
  range: SpreadsheetCellRange;
111
+ scope?: SpreadsheetSortOwnedScope;
95
112
  sheetId: string;
96
113
  }
97
114
  export interface SpreadsheetSortField {
@@ -106,11 +123,12 @@ export interface SpreadsheetSortDialogSource {
106
123
  range: SpreadsheetCellRange;
107
124
  rangeReference: string;
108
125
  rows: SpreadsheetSortField[];
126
+ scope?: SpreadsheetSortOwnedScope;
109
127
  sheetId: string;
110
128
  sheetName: string;
111
129
  value: SpreadsheetSortDialogValue;
112
130
  }
113
- export type SpreadsheetSortErrorCode = 'column-out-of-range' | 'duplicate-key' | 'formula-reference-out-of-range' | 'invalid-appearance' | 'invalid-case-sensitivity' | 'invalid-custom-list' | 'invalid-direction' | 'invalid-header' | 'invalid-matrix' | 'invalid-orientation' | 'invalid-range' | 'invalid-text-method' | 'missing-key' | 'not-enough-columns' | 'not-enough-rows' | 'range-too-large' | 'row-out-of-range' | 'too-many-keys' | 'unsupported-text-method' | 'unsupported-linked-cell';
131
+ export type SpreadsheetSortErrorCode = 'column-out-of-range' | 'duplicate-key' | 'formula-reference-out-of-range' | 'invalid-appearance' | 'invalid-case-sensitivity' | 'invalid-custom-list' | 'invalid-direction' | 'invalid-header' | 'invalid-matrix' | 'invalid-orientation' | 'invalid-range' | 'invalid-scope' | 'invalid-text-method' | 'missing-key' | 'not-enough-columns' | 'not-enough-rows' | 'range-too-large' | 'row-out-of-range' | 'too-many-keys' | 'unsupported-text-method' | 'unsupported-linked-cell';
114
132
  export type SpreadsheetSortValidationResult = {
115
133
  ok: true;
116
134
  request: SpreadsheetSortNormalizedRequest;
@@ -122,6 +140,7 @@ export type SpreadsheetSortValidationResult = {
122
140
  export type SpreadsheetSortResult = {
123
141
  ok: true;
124
142
  rows: (Cell | null)[][];
143
+ sourceIndexes: number[];
125
144
  } | {
126
145
  code: SpreadsheetSortErrorCode;
127
146
  message: string;
@@ -130,6 +149,9 @@ export type SpreadsheetSortResult = {
130
149
  export declare function createSpreadsheetSortRangePlan(sheet: WorkSpreadsheetSheet, selectedRange: SpreadsheetCellRange): SpreadsheetSortRangePlan | null;
131
150
  export declare function createSpreadsheetSortRangeDialogSource(sheetName: string, request: SpreadsheetSortOpenRequest): SpreadsheetSortRangeDialogSource | null;
132
151
  export declare function createSpreadsheetSortDialogSource(sheetId: string, sheetName: string, target: SpreadsheetSortTarget, rows: readonly (readonly (Cell | null)[])[], customLists?: readonly SpreadsheetSortCustomList[], appearanceRows?: SpreadsheetSortAppearanceRows): SpreadsheetSortDialogSource | null;
152
+ export declare function spreadsheetSortRowsMatchRange(rows: readonly (readonly (Cell | null)[])[], range: SpreadsheetCellRange): boolean;
153
+ export declare function spreadsheetSortRowsFromSheet(sheet: WorkSpreadsheetSheet, range: SpreadsheetCellRange): (Cell | null)[][] | null;
154
+ export declare function spreadsheetSortOwnedRangeForExactRange(sheet: WorkSpreadsheetSheet, range: SpreadsheetCellRange): SpreadsheetSortOwnedRange | null;
133
155
  export declare function validateSpreadsheetSortRequest(request: SpreadsheetSortRequest): SpreadsheetSortValidationResult;
134
156
  export declare function spreadsheetSortFailureMessage(result: SpreadsheetSortValidationResult | SpreadsheetSortResult): string | null;
135
157
  export declare function spreadsheetSortAppearanceRowsMatch(rows: readonly (readonly (Cell | null)[])[], appearances: SpreadsheetSortAppearanceRows): boolean;
@@ -10,5 +10,8 @@ export declare function workSpreadsheetAutoFilterCriteriaEntries(sheet: WorkSpre
10
10
  export declare function workSpreadsheetSheetWithAutoFilterCriteria(sheet: WorkSpreadsheetSheet, column: number, criteria: WorkSpreadsheetFilterCriteria, context?: WorkSpreadsheetDynamicFilterContext): WorkSpreadsheetSheet | null;
11
11
  export declare function workSpreadsheetSheetWithoutAutoFilterCriteria(sheet: WorkSpreadsheetSheet, column: number): WorkSpreadsheetSheet | null;
12
12
  export declare function workSpreadsheetAutoFilterManuallyHiddenRows(sheet: WorkSpreadsheetSheet): Set<string>;
13
+ export declare function workSpreadsheetAutoFilterOwnedRows(sheet: WorkSpreadsheetSheet): Set<string>;
14
+ export declare function workSpreadsheetFilterHiddenRows(sheet: WorkSpreadsheetSheet, range: WorkSpreadsheetAutoFilterRange, column: number, criteria: WorkSpreadsheetFilterCriteria, context?: WorkSpreadsheetDynamicFilterContext): Record<string, 0> | null;
15
+ export declare function workSpreadsheetSheetWithReappliedAutoFilterCriteria(sheet: WorkSpreadsheetSheet, criteriaSource: WorkSpreadsheetSheet, manuallyHiddenRows: ReadonlySet<string>, context?: WorkSpreadsheetDynamicFilterContext): WorkSpreadsheetSheet;
13
16
  export declare function workSpreadsheetSheetWithImportedAutoFilterCriteria(sheet: WorkSpreadsheetSheet, entries: readonly WorkSpreadsheetFilter[], context?: WorkSpreadsheetDynamicFilterContext): WorkSpreadsheetSheet;
14
17
  export declare function normalizeWorkSpreadsheetFilterCriteria(criteria: unknown): WorkSpreadsheetFilterCriteria | null;
@@ -1,7 +1,8 @@
1
1
  import type { Cell } from '@fortune-sheet/core';
2
- import type { WorkSpreadsheetDynamicFilter } from './work-types';
2
+ import type { WorkSpreadsheetDateSystem, WorkSpreadsheetDynamicFilter } from './work-types';
3
3
  export interface WorkSpreadsheetDynamicFilterContext {
4
+ dateSystem?: WorkSpreadsheetDateSystem;
4
5
  now: Date;
5
6
  }
6
7
  export declare function workSpreadsheetDynamicFilterMatcher(kind: WorkSpreadsheetDynamicFilter, cells: Iterable<Cell | null>, context: WorkSpreadsheetDynamicFilterContext): ((cell: Cell | null) => boolean) | null;
7
- export declare function workSpreadsheetCellIsDate(cell: Cell | null): boolean;
8
+ export declare function workSpreadsheetCellIsDate(cell: Cell | null, dateSystem?: WorkSpreadsheetDateSystem): boolean;
@@ -182,9 +182,12 @@ export interface WorkDocumentComment {
182
182
  resolved: boolean;
183
183
  replies?: WorkDocumentCommentReply[];
184
184
  }
185
+ export type WorkSpreadsheetDateSystem = '1900' | '1904';
185
186
  export interface WorkSpreadsheetContent {
186
187
  type: 'spreadsheet';
187
188
  sheets: WorkSpreadsheetSheet[];
189
+ /** Omitted values use the Excel-compatible 1900 date system. */
190
+ dateSystem?: WorkSpreadsheetDateSystem;
188
191
  calculation?: WorkSpreadsheetCalculationSettings;
189
192
  namedRanges?: WorkSpreadsheetNamedRange[];
190
193
  printAreas?: WorkSpreadsheetPrintArea[];
Binary file
package/dist/styles.css CHANGED
@@ -18068,6 +18068,13 @@ sub [data-office-character-position-half-points], sup [data-office-character-pos
18068
18068
  font-weight: 700;
18069
18069
  }
18070
18070
 
18071
+ .work-spreadsheet-sort-options-lock-note {
18072
+ color: var(--a3s-muted);
18073
+ margin: 0 0 2px;
18074
+ font-size: 11px;
18075
+ line-height: 1.45;
18076
+ }
18077
+
18071
18078
  .work-spreadsheet-sort-options > label {
18072
18079
  border: 1px solid var(--a3s-line);
18073
18080
  cursor: pointer;