From 1c63bc0c3db46e21c8444db13e4aa022ae893da5 Mon Sep 17 00:00:00 2001 From: wpxp123456 <2677556700@qq.com> Date: Tue, 23 Dec 2025 18:49:17 +0800 Subject: [PATCH] fix(api): fix getVisibleRange api and add getVisibleRangesOfAllViewports api (#6368) --- .../sheets/sheet.render-skeleton.ts | 21 +++++-- packages/sheets-ui/src/facade/f-enum.ts | 42 ++++++++++++++ packages/sheets-ui/src/facade/f-worksheet.ts | 56 +++++++++++-------- packages/sheets-ui/src/facade/index.ts | 3 +- 4 files changed, 93 insertions(+), 29 deletions(-) create mode 100644 packages/sheets-ui/src/facade/f-enum.ts diff --git a/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts b/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts index 3682102eca..d486d0977d 100644 --- a/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts +++ b/packages/engine-render/src/components/sheets/sheet.render-skeleton.ts @@ -1215,11 +1215,24 @@ export class SpreadsheetSkeleton extends SheetSkeleton { // viewBound contains header, so need to subtract the header height and margin const startRow = searchArray(rowHeightAccumulation, Math.round(viewBound.top) - this.columnHeaderHeightAndMarginTop); - const endRow = searchArray(rowHeightAccumulation, Math.round(viewBound.bottom) - this.columnHeaderHeightAndMarginTop); - const startColumn = searchArray(columnWidthAccumulation, Math.round(viewBound.left) - this.rowHeaderWidthAndMarginLeft); - const endColumn = searchArray(columnWidthAccumulation, Math.round(viewBound.right) - this.rowHeaderWidthAndMarginLeft); - // If the get range is used for printing, the endRow and endColumn do not need to minus 1. + const endY = Math.round(viewBound.bottom) - this.columnHeaderHeightAndMarginTop; + let endRow = searchArray(rowHeightAccumulation, endY); + // If the endY is exactly on the boundary, need to minus 1 to get the correct endRow. + if (endRow < lenOfRowData && rowHeightAccumulation[endRow - 1] === endY) { + endRow -= 1; + } + + const startColumn = searchArray(columnWidthAccumulation, Math.round(viewBound.left) - this.rowHeaderWidthAndMarginLeft); + + const endX = Math.round(viewBound.right) - this.rowHeaderWidthAndMarginLeft; + let endColumn = searchArray(columnWidthAccumulation, endX); + // If the endX is exactly on the boundary, need to minus 1 to get the correct endColumn. + if (endColumn < lenOfColData && columnWidthAccumulation[endColumn - 1] === endX) { + endColumn -= 1; + } + + // If the get range is used for visible range, the endRow and endColumn need to minus 1. if (isPrinting) { return { startRow, diff --git a/packages/sheets-ui/src/facade/f-enum.ts b/packages/sheets-ui/src/facade/f-enum.ts new file mode 100644 index 0000000000..28d32f2c32 --- /dev/null +++ b/packages/sheets-ui/src/facade/f-enum.ts @@ -0,0 +1,42 @@ +/** + * Copyright 2023-present DreamNum Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FEnum } from '@univerjs/core/facade'; +import { SHEET_VIEWPORT_KEY } from '@univerjs/engine-render'; + +/** + * @ignore + */ +export interface IFSheetsUIEnum { + /** + * Sheet value change command types. These commands affect the content or style of cells. + * Includes operations like setting cell values, moving ranges, merging cells, and applying styles. + */ + SHEET_VIEWPORT_KEY: typeof SHEET_VIEWPORT_KEY; +} + +export class FSheetsUIEnum implements IFSheetsUIEnum { + get SHEET_VIEWPORT_KEY(): typeof SHEET_VIEWPORT_KEY { + return SHEET_VIEWPORT_KEY; + } +} + +FEnum.extend(FSheetsUIEnum); +declare module '@univerjs/core/facade' { + // eslint-disable-next-line ts/naming-convention + export interface FEnum extends IFSheetsUIEnum { + } +} diff --git a/packages/sheets-ui/src/facade/f-worksheet.ts b/packages/sheets-ui/src/facade/f-worksheet.ts index 293fbacbaf..3b677133cd 100644 --- a/packages/sheets-ui/src/facade/f-worksheet.ts +++ b/packages/sheets-ui/src/facade/f-worksheet.ts @@ -21,7 +21,7 @@ import type { ISelectionStyle } from '@univerjs/sheets'; import type { IScrollState, IViewportScrollState } from '@univerjs/sheets-ui'; import type { FRange } from '@univerjs/sheets/facade'; import { ICommandService, toDisposable } from '@univerjs/core'; -import { IRenderManagerService, SHEET_VIEWPORT_KEY, sheetContentViewportKeys } from '@univerjs/engine-render'; +import { IRenderManagerService, SHEET_VIEWPORT_KEY } from '@univerjs/engine-render'; import { SetWorksheetRowIsAutoHeightCommand } from '@univerjs/sheets'; import { IMarkSelectionService, SetColumnHeaderHeightCommand, SetRowHeaderWidthCommand, SetWorksheetColAutoWidthCommand, SetZoomRatioCommand, SHEET_VIEW_KEY, SheetScrollManagerService, SheetSkeletonManagerService, SheetsScrollRenderController } from '@univerjs/sheets-ui'; import { FWorksheet } from '@univerjs/sheets/facade'; @@ -92,7 +92,7 @@ export interface IFWorksheetSkeletonMixin { getZoom(): number; /** - * Return visible range, sum view range of 4 viewports. + * Get visible range of main viewport. * @returns {IRange} - visible range * @example * ```ts @@ -103,7 +103,22 @@ export interface IFWorksheetSkeletonMixin { * console.log(fWorksheet.getRange(visibleRange).getA1Notation()); * ``` */ - getVisibleRange(): IRange; + getVisibleRange(): IRange | null; + + /** + * Get visible ranges of all viewports. + * @returns {Record} - visible ranges of all viewports + * @example + * ```ts + * const fWorkbook = univerAPI.getActiveWorkbook(); + * const fWorksheet = fWorkbook.getActiveSheet(); + * const visibleRanges = fWorksheet.getVisibleRangesOfAllViewports(); + * console.log(visibleRanges); + * const mainLeftTopViewportRange = visibleRanges?.get(univerAPI.Enum.SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT_TOP); + * console.log(fWorksheet.getRange(mainLeftTopViewportRange).getA1Notation()); + * ``` + */ + getVisibleRangesOfAllViewports(): Map | null; /** * Scroll spreadsheet(viewMain) to cell position. Make the cell at topleft of current viewport. @@ -367,33 +382,26 @@ export class FWorksheetSkeletonMixin extends FWorksheet implements IFWorksheetSk return this._worksheet.getZoomRatio(); } - override getVisibleRange(): IRange { + override getVisibleRange(): IRange | null { const unitId = this._workbook.getUnitId(); const renderManagerService = this._injector.get(IRenderManagerService); const render = renderManagerService.getRenderById(unitId); - let range: IRange = { - startColumn: 0, - startRow: 0, - endColumn: 0, - endRow: 0, - }; - if (!render) return range; + if (!render) return null; const skm = render.with(SheetSkeletonManagerService); const sk = skm.getCurrentSkeleton(); - if (!sk) return range; - const visibleRangeMap = sk?.getVisibleRanges(); - if (!visibleRangeMap) return range; + if (!sk) return null; + return sk.getVisibleRangeByViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN) as IRange; + } - range = sk.getVisibleRangeByViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN) as IRange; - for (const [k, r] of visibleRangeMap) { - if (sheetContentViewportKeys.indexOf(k) === -1) continue; - range.startColumn = Math.min(range.startColumn, r.startColumn); - range.startRow = Math.min(range.startRow, r.startRow); - range.endColumn = Math.max(range.endColumn, r.endColumn); - range.endRow = Math.max(range.endRow, r.endRow); - } - - return range; + override getVisibleRangesOfAllViewports(): Map | null { + const unitId = this._workbook.getUnitId(); + const renderManagerService = this._injector.get(IRenderManagerService); + const render = renderManagerService.getRenderById(unitId); + if (!render) return null; + const skm = render.with(SheetSkeletonManagerService); + const sk = skm.getCurrentSkeleton(); + if (!sk) return null; + return sk.getVisibleRanges(); } override scrollToCell(row: number, column: number, duration?: number): FWorksheet { diff --git a/packages/sheets-ui/src/facade/index.ts b/packages/sheets-ui/src/facade/index.ts index 340ed736f6..5cd763d6fc 100644 --- a/packages/sheets-ui/src/facade/index.ts +++ b/packages/sheets-ui/src/facade/index.ts @@ -21,8 +21,9 @@ import './f-permission'; import './f-sheet-hooks'; import './f-event'; -export type * from './f-event'; +export * from './f-enum'; +export type * from './f-event'; export type * from './f-permission'; export { type IFComponentKey, transformComponentKey } from './f-range'; export type * from './f-sheet-hooks';