일반 API

Univer에서 사용할 수 있는 Facade API는 문서 유형에 따라 다릅니다. 이 섹션에서는 모든 문서 유형에 적용되는 일반 Facade API를 소개합니다.

가져오기

TypeScript
import { FUniver } from '@univerjs/core/facade'const univerAPI = FUniver.newAPI(univer)

개념

명령

Univer의 작업 대부분은 명령 시스템에 등록되고 명령 시스템을 통해 실행됩니다. 이렇게 작업 방식을 통합하면 실행 취소, 다시 실행, 협업 등의 기능을 Univer에서 손쉽게 구현할 수 있습니다.

설계에 대한 자세한 내용은 Univer 명령 시스템을 참고하세요.

명령

Univer의 작업 대부분은 명령 시스템에 등록되고 명령 시스템을 통해 실행됩니다. 이렇게 작업 방식을 통합하면 실행 취소, 다시 실행, 협업 등의 기능을 Univer에서 손쉽게 구현할 수 있습니다.

명령은 Univer 내의 고유한 "이벤트"로 간단히 이해할 수 있습니다. 설계에 대한 자세한 내용은 명령 시스템을 참고하세요.

명령 수신

Univer는 명령 실행 전과 실행 후, 두 가지 시점에 명령을 수신할 수 있는 방법을 제공합니다.

  • Event.BeforeCommandExecute: 명령이 실행되기 전에 사용자 지정 로직을 실행합니다.
  • Event.CommandExecuted: 명령이 실행된 후에 사용자 지정 로직을 실행합니다.

실행 전 명령 수신

실행 전에는 Event.BeforeCommandExecute를 FUniver.addEvent에 전달하여 전처리 리스너를 등록합니다.

명령이 실행되면 전처리 리스너 내부의 로직이 실행됩니다.

TypeScript
const univerAPI = FUniver.newAPI(univer)univerAPI.addEvent(univerAPI.Event.BeforeCommandExecute, ({ id, type, params }) => {  // Custom logic executed before the command is executed})

명령 실행을 막으려면 리스너에서 event.cancel을 true로 설정합니다.

TypeScript
const univerAPI = FUniver.newAPI(univer)univerAPI.addEvent(univerAPI.Event.BeforeCommandExecute, (event) => {  event.cancel = true})

실행 후 명령 수신

실행 후에는 Event.CommandExecuted를 FUniver.addEvent에 전달하여 후처리 리스너를 등록합니다.

명령이 실행되면 후처리 리스너 내부의 로직이 실행됩니다.

TypeScript
const univerAPI = FUniver.newAPI(univer)univerAPI.addEvent(univerAPI.Event.CommandExecuted, ({ id, type, params }) => {  // Custom logic executed after the command is executed})

수신 취소

명령 리스너를 등록하는 메서드는 IDisposable 객체를 반환하며, IDisposable.dispose를 호출하여 제거할 수 있습니다.

프로그램의 안정성을 높이려면 더 이상 사용하지 않는 리스너를 제거하는 것이 좋습니다.

TypeScript
const univerAPI = FUniver.newAPI(univer)// Register a listenerconst disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommandExecute, () => {  // custom preprocessing logic before the command is executed})// Example: Destroy the listener after 1 secondsetTimeout(() => {  // Destroy the listener  disposable.dispose()}, 1000)

명령 실행

명령 ID와 전달해야 할 매개변수를 알고 있다면 FUniver.executeCommand 메서드로 명령을 실행할 수도 있습니다.

예를 들어 sheet.command.set-range-values 명령을 사용하여 A1 셀의 값을 설정할 수 있습니다.

TypeScript
const univerAPI = FUniver.newAPI(univer)// Execute the commanduniverAPI.executeCommand('sheet.command.set-range-values', {  value: { v: 'Hello, Univer!' },  range: { startRow: 0, startColumn: 0, endRow: 0, endColumn: 0 },})

이벤트 API

Univer는 스프레드시트의 다양한 변경 사항을 수신하고 이에 대응할 수 있는 포괄적인 이벤트 시스템을 제공합니다. 이벤트는 클립보드 작업, 선택 영역 변경, 셀 상호 작용, 시트 수정 등을 포함한 여러 그룹으로 크게 나눌 수 있습니다.

이벤트 범주

전체 이벤트 목록: /reference/facade/events

  1. 클립보드 이벤트

    • BeforeClipboardChange: 클립보드 내용이 변경되기 전에 실행되며, params.cancel = true를 설정하여 변경을 막을 수 있습니다.
    • BeforeClipboardPaste: 내용을 붙여넣기 전에 실행되며, params.cancel = true를 설정하여 붙여넣기를 막을 수 있습니다.
    • ClipboardChanged: 클립보드 내용이 변경된 후에 실행되며, 새 클립보드 내용을 제공합니다.
    • ClipboardPasted: 내용을 붙여넣은 후에 실행되며, 붙여넣은 내용을 제공합니다.
  2. 선택 영역 이벤트

    • SelectionChanged: 선택 영역이 변경될 때 실행되며, 새 선택 범위 정보를 제공합니다.
    • SelectionMoveStart: 선택 영역 이동이 시작될 때 실행되며, 사용자 지정 선택 효과에 유용합니다.
    • SelectionMoveEnd: 선택 영역 이동이 끝날 때 실행되며, 최종 선택 범위를 제공합니다.
    • SelectionMoving: 선택 영역을 이동하는 동안 실행되며, 실시간 UI 업데이트에 유용합니다.
    • DragOver: 셀 위로 드래그할 때 실행됩니다.
    • Drop: 선택한 내용을 놓을 때 실행됩니다.
  3. 셀 이벤트

    • CellClicked: 셀을 클릭할 때 실행되며, 셀 위치와 내용 정보를 제공합니다.
    • CellHover: 셀 위에 마우스 포인터를 올릴 때 실행되며, 툴팁을 표시하는 데 유용합니다.
    • CellPointerDown: 셀에서 포인터를 누를 때 실행되며, 드래그 또는 선택 작업을 시작하는 데 사용됩니다.
    • CellPointerUp: 셀에서 포인터를 놓을 때 실행되며, 작업을 완료하는 데 사용됩니다.
    • CellPointerMove: 셀 위에서 포인터를 움직일 때 실행됩니다.
  4. 시트 이벤트

    • SheetValueChanged: 시트 값이 변경될 때 실행되며, 변경된 범위와 새 값을 제공합니다.
    • SheetZoomChanged: 확대/축소 수준이 변경될 때 실행되며, 새 확대/축소 비율을 제공합니다.
    • SheetSkeletonChanged: 행/열 삽입 또는 삭제 등 시트 구조가 변경될 때 실행됩니다.
    • BeforeSheetEditStart: 셀 편집이 시작되기 전에 실행되며, 편집 허용 여부를 제어할 수 있습니다.
    • SheetEditStarted: 셀 편집이 시작될 때 실행되며, 사용자 지정 편집기 동작에 유용합니다.
    • BeforeSheetEditEnd: 셀 편집이 끝나기 전에 실행되며, 내용 검증에 사용할 수 있습니다.
    • SheetEditEnded: 셀 편집이 끝날 때 실행되며, 편집된 값을 제공합니다.
    • SheetEditChanging: 셀을 편집하는 동안 실행되며, 실시간 검증 또는 서식 지정에 유용합니다.
    • Scroll: 시트를 스크롤할 때 실행되며, 스크롤 위치 정보를 제공합니다.
    • CrosshairHighlightColorChanged: 십자선 강조 색상이 변경될 때 실행됩니다.
    • CrosshairHighlightEnabledChanged: 십자선 강조가 활성화되거나 비활성화될 때 실행됩니다.
  5. 헤더 이벤트

    • RowHeaderClick: 행 헤더를 클릭할 때 실행됩니다.
    • RowHeaderHover: 행 헤더 위에 마우스 포인터를 올릴 때 실행됩니다.
    • ColumnHeaderClick: 열 헤더를 클릭할 때 실행됩니다.
    • ColumnHeaderHover: 열 헤더 위에 마우스 포인터를 올릴 때 실행됩니다.
  6. 데이터 유효성 검사 이벤트

    • BeforeSheetDataValidationAdd: 데이터 유효성 검사 규칙을 추가하기 전에 실행됩니다.
    • SheetDataValidationChanged: 데이터 유효성 검사 규칙이 변경될 때 실행됩니다.
    • SheetDataValidatorStatusChanged: 데이터 유효성 검사 상태가 변경될 때 실행됩니다.
  7. 댓글 이벤트

    • BeforeCommentAdd: 댓글을 추가하기 전에 실행됩니다.
    • CommentAdded: 댓글을 추가한 후에 실행됩니다.
    • BeforeCommentUpdate: 댓글을 업데이트하기 전에 실행됩니다.
    • CommentUpdated: 댓글을 업데이트한 후에 실행됩니다.
    • BeforeCommentDeleted: 댓글을 삭제하기 전에 실행됩니다.
    • CommentDeleted: 댓글을 삭제한 후에 실행됩니다.
  8. 데이터 처리 이벤트

    • SheetBeforeRangeSort: 범위를 정렬하기 전에 실행됩니다.
    • SheetRangeSorted: 범위를 정렬한 후에 실행됩니다.
    • SheetBeforeRangeFilter: 범위를 필터링하기 전에 실행됩니다.
    • SheetRangeFiltered: 범위를 필터링한 후에 실행됩니다.
    • BeforePivotTableAdd: 피벗 테이블을 추가하기 전에 실행됩니다.
    • PivotTableAdded: 피벗 테이블을 추가한 후에 실행됩니다.

이벤트 사용

univerAPI의 addEvent 메서드를 사용하여 이벤트를 수신할 수 있습니다. 기본 패턴은 다음과 같습니다.

TypeScript
univerAPI.addEvent(univerAPI.Event.EventName, (params) => {  // Handle event parameters})

예시: 셀 클릭 수신

TypeScript
univerAPI.addEvent(univerAPI.Event.CellClicked, (params) => {  const { worksheet, workbook, row, column } = params  console.log(`Cell clicked at row ${row}, column ${column}`)})

예시: 클립보드 작업 모니터링

TypeScript
univerAPI.addEvent(univerAPI.Event.BeforeClipboardPaste, (params) => {  const { text, html } = params  // If you want to cancel the clipboard paste  params.cancel = true})

예시: 선택 영역 변경 추적

TypeScript
univerAPI.addEvent(univerAPI.Event.SelectionChanged, (params) => {  const { worksheet, workbook, selections } = params  console.log('Selection changed:', selections)})

이벤트 리스너 취소

이벤트 리스너는 더 이상 필요하지 않을 때 리스너를 제거하는 데 사용할 수 있는 IDisposable 객체를 반환합니다.

TypeScript
const disposable = univerAPI.addEvent(univerAPI.Event.SheetValueChanged, (params) => {  // Handle value changes})// Later, when you want to remove the listener:disposable.dispose()

모범 사례

  1. 메모리 누수를 방지하려면 더 이상 필요하지 않은 이벤트 리스너를 항상 제거하세요.
  2. 사용 사례에 적합한 이벤트를 사용하고, 일반 이벤트보다 구체적인 이벤트를 우선하세요.
  3. 성능을 유지할 수 있도록 이벤트 핸들러를 가볍게 구성하세요.
  4. 기본 동작을 막아야 할 때는 BeforeClipboardChange 및 이와 유사한 "before" 이벤트를 사용하는 것이 좋습니다.

실행 취소 및 다시 실행

실행 취소

TypeScript
await univerAPI.undo()

다시 실행

TypeScript
await univerAPI.redo()

시스템 클립보드

FUniver.copy() 및 FUniver.paste() 메서드를 사용하면 시스템 클립보드에서 데이터를 읽고 쓸 수 있습니다.

복사와 붙여넣기는 브라우저의 네이티브 API에 의존합니다. 환경 조건이나 권한이 충분하지 않으면 복사 및 붙여넣기 기능이 작동하지 않습니다. 자세한 내용은 MDN 문서를 참고하세요.

예시: 시트 범위에서 복사 및 붙여넣기

TypeScript
// Prevent failure due to loss of focus when executing copy and paste code in the console,// this example listens for the cell click event and executes the copy and paste code.univerAPI.addEvent(univerAPI.Event.CellClicked, async (params) => {  const fWorkbook = univerAPI.getActiveWorkbook()  const fWorksheet = fWorkbook.getActiveSheet()  // Copy the range A1:B2 to the clipboard  const fRange = fWorksheet.getRange('A1:B2')  fRange.activate().setValues([    [1, 2],    [3, 4],  ])  await univerAPI.copy()  // Paste the copied content to the range C1:D2  const fRange2 = fWorksheet.getRange('C1')  fRange2.activate()  await univerAPI.paste()  // Check the pasted content  console.log(fWorksheet.getRange('C1:D2').getValues()) // [[1, 2], [3, 4]]})

또는 명령 시스템을 사용하여 클립보드 기능을 호출할 수 있습니다.

TypeScript
import { CopyCommand, PasteCommand } from '@univerjs/ui'// CopyuniverAPI.executeCommand(CopyCommand.id)// PasteuniverAPI.executeCommand(PasteCommand.id)

UI

Univer UI를 확장하려면 다음 문서를 참고하세요.

WebSocket

Facade API는 URL을 전달하여 WebSocket을 생성할 수 있는 편리한 createSocket API를 제공합니다. 그런 다음 open, message, close 및 error 이벤트를 수신하고, send 메서드로 메시지를 직접 전송하거나 close 메서드로 연결을 닫을 수 있습니다.

Presets 설치 방식에서는 univerAPI.createSocket(url)을 바로 사용하세요. 개별 설치 방식을 사용하는 경우 @univerjs/network 종속성 패키지를 설치하고 UniverNetworkPlugin 플러그인을 등록해야 합니다.

TypeScript
// ... Omits other plugin importsimport { UniverNetworkPlugin } from '@univerjs/network'// ... Omits other facade importsimport '@univerjs/network/facade'// ... Omits other plugin registrationsuniver.registerPlugin(UniverNetworkPlugin)

간단한 예시는 다음과 같습니다.

TypeScript
// Replace the URL with the address of your own WebSocket serviceconst ws = univerAPI.createSocket('ws://47.100.177.253:8449/ws')ws.open$.subscribe(() => {  console.log('websocket opened')  ws.send('hello')})ws.message$.subscribe((message) => {  console.log('websocket message', message)  const content = JSON.parse(message.data).content  if (!content.includes('command')) {    return  }  const commandInfo = JSON.parse(content)  const { command, options } = commandInfo  const { id, params } = command  // Upon receiving collaborative data, it is locally saved  univerAPI.executeCommand(id, params, options)})ws.close$.subscribe(() => {  console.log('websocket closed')})ws.error$.subscribe((error) => {  console.log('websocket error', error)})univerAPI.addEvent(univerAPI.Event.CommandExecuted, ({ id, type, params, options }) => {  // Only synchronize local mutations  if (    type !== univerAPI.Enum.CommandType.MUTATION ||    options?.fromCollab ||    options?.onlyLocal ||    id === 'doc.mutation.rich-text-editing'  ) {    return  }  const commandInfo = JSON.stringify({ command: { id, type, params }, options: { fromCollab: true } })  ws.send(commandInfo)})

참고: Univer를 시작할 때 unitID가 있어야 합니다. unitID를 지정하지 않으면 협업 기능이 작동하지 않습니다.

수식 등록

Facade API를 사용하면 현재 Univer 인스턴스에 사용자 지정 수식을 빠르고 간편하게 등록할 수 있습니다.

다음 예시와 같이 registerFunction을 사용하면 CUSTOMSUM 수식에 필요한 알고리즘, 이름 및 설명을 수식 플러그인에 한 번에 등록할 수 있습니다. 실행한 후에는 해당 수식을 사용할 수 있습니다. 빈 셀에 =CUSTOMSUM을 입력하면 안내가 표시됩니다.

TypeScript
// Registered formulas support lambda functionsconst formulaEngine = univerAPI.getFormula()formulaEngine.registerFunction(  'CUSTOMSUM',  (...variants) => {    let sum = 0    const last = variants[variants.length - 1]    if (last.isLambda && last.isLambda()) {      variants.pop()      const variantsList = variants.map((variant) => (Array.isArray(variant) ? variant[0][0] : variant))      sum += last.executeCustom(...variantsList).getValue()    }    for (const variant of variants) {      sum += Number(variant) || 0    }    return sum  },  'Adds its arguments',)// Use the function in a cellconst fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const cellA1 = fWorksheet.getRange('A1')cellA1.setValue(1)const cellA2 = fWorksheet.getRange('A2')cellA2.setValue(2)const cellA3 = fWorksheet.getRange('A3')cellA3.setValue({ f: '=CUSTOMSUM(A1,A2,LAMBDA(x,y,x*y))' })// A3 will display: 5formulaEngine.calculationEnd((functionsExecutedState) => {  if (functionsExecutedState === 3) {    console.log(cellA3.getValue()) // 5  }})

수식 등록을 해제해야 한다면 dispose 메서드를 호출할 수 있습니다.

TypeScript
const functionDisposable = formulaEngine.registerFunction({  // calculate})// Unregister the functionfunctionDisposable.dispose()

더 완전한 다국어 콘텐츠와 설명을 제공하려면 locales 및 description 필드를 구성할 수도 있습니다. 예시는 다음과 같습니다.

TypeScript
formulaEngine.registerFunction(  'CUSTOMSUM',  (...variants) => {    let sum = 0    const last = variants[variants.length - 1]    if (last.isLambda && last.isLambda()) {      variants.pop()      const variantsList = variants.map((variant) => (Array.isArray(variant) ? variant[0][0] : variant))      sum += last.executeCustom(...variantsList).getValue()    }    for (const variant of variants) {      sum += Number(variant) || 0    }    return sum  },  {    description: {      functionName: 'CUSTOMSUM',      description: 'formulaCustom.CUSTOMSUM.description',      abstract: 'formulaCustom.CUSTOMSUM.abstract',      functionParameter: [        {          name: 'formulaCustom.CUSTOMSUM.functionParameter.number1.name',          detail: 'formulaCustom.CUSTOMSUM.functionParameter.number1.detail',          example: 'A1:A20',          require: 1,          repeat: 0,        },        {          name: 'formulaCustom.CUSTOMSUM.functionParameter.number2.name',          detail: 'formulaCustom.CUSTOMSUM.functionParameter.number2.detail',          example: 'B2:B10',          require: 0,          repeat: 1,        },      ],    },    locales: {      zhCN: {        formulaCustom: {          CUSTOMSUM: {            description: '将单个值、单元格引用或是区域相加,或者将三者的组合相加。',            abstract: '求参数的和',            functionParameter: {              number1: {                name: '数值1',                detail:                  '要相加的第一个数字。 该数字可以是 4 之类的数字,B6 之类的单元格引用或 B2:B8 之类的单元格范围。',              },              number2: {                name: '数值2',                detail: '这是要相加的第二个数字。 可以按照这种方式最多指定 255 个数字。',              },            },          },        },      },      enUS: {        formulaCustom: {          CUSTOMSUM: {            description: `You can add individual values, cell references or ranges or a mix of all three.`,            abstract: `Adds its arguments`,            functionParameter: {              number1: {                name: 'number1',                detail:                  'The first number you want to add. The number can be like 4, a cell reference like B6, or a cell range like B2:B8.',              },              number2: {                name: 'number2',                detail: 'This is the second number you want to add. You can specify up to 255 numbers in this way.',              },            },          },        },      },    },  },)

참고

  • func에는 계산 수식의 구체적인 알고리즘과 이름 매핑을 작성합니다. 입력 매개변수는 사용자가 수식을 사용할 때 입력한 내용이며, 숫자, 문자열, 불리언 값 또는 배열일 수 있습니다.
  • description은 사용자 지정 수식의 설명을 설정합니다.
  • locales 아래에 여러 언어를 설정할 수 있습니다. 명명 규칙은 LocaleType을 참고하세요. functionList 아래에 여러 수식의 번역을 추가할 수 있습니다. 필드에 대한 자세한 설명은 Formula Engine에 수식을 추가하는 방법 섹션을 참고하세요.

수식 시스템에서 제공하는 알고리즘을 재사용하고 수식 알고리즘의 기능을 확장하려면 플러그인 구성을 통해 사용자 지정 수식을 등록할 수 있습니다. 자세한 튜토리얼은 사용자 지정 수식을 참고하세요.

열거형 API

Facade API는 개발 중에 사용할 수 있는 몇 가지 자주 쓰이는 열거형을 제공합니다. 예시는 다음과 같습니다.

TypeScript
console.log(univerAPI.Enum)console.log(univerAPI.Enum.UniverInstanceType.UNIVER_SHEET)console.log(univerAPI.Enum.LifecycleStages.Rendered)

유틸리티 메서드 API

Facade API는 개발 중에 사용할 수 있는 몇 가지 자주 쓰이는 유틸리티 메서드를 제공합니다. 예시는 다음과 같습니다.

TypeScript
console.log(univerAPI.Util)console.log(univerAPI.Util.tools.chatAtABC(10))console.log(univerAPI.Util.tools.ABCatNum('K'))

이 가이드는 어떠셨나요?

© 2026 DreamNum Co., Ltd.