# 打印

- Human documentation: [https://docs.univer.ai/zh-CN/guides/sheets/features/print](https://docs.univer.ai/zh-CN/guides/sheets/features/print)

- Agent Markdown: [https://docs.univer.ai/zh-CN/guides/sheets/features/print.md](https://docs.univer.ai/zh-CN/guides/sheets/features/print.md)

- Requested language: `zh-CN`

- Content language: `zh-CN`

- Documentation version: `1.0.0-rc.0`

- Source: [sheets/features/print.zh-CN.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/features/print.zh-CN.mdx)

---

#### Package metadata

```json
{
  "preset": [
    {
      "client": "@univerjs/preset-sheets-advanced",
      "locale": "@univerjs/preset-sheets-advanced/locales/zh-CN",
      "style": "@univerjs/preset-sheets-advanced/lib/index.css"
    }
  ],
  "plugins": [
    {
      "client": "@univerjs-pro/sheets-print",
      "facade": "@univerjs-pro/sheets-print/facade",
      "locale": "@univerjs-pro/sheets-print/locale/zh-CN",
      "style": "@univerjs-pro/sheets-print/lib/index.css"
    }
  ],
  "license": true,
  "server": false
}
```

打印功能允许用户将表格内容打印为纸质文档或导出为 PDF 格式，便于离线查看和分享。

> Interactive example: [Open the playground](/playground/sheets/print)

## 预设模式

打印功能被包含在 `@univerjs/preset-sheets-advanced` 预设中。

### 安装

> [!NOTE]
> @univerjs/preset-sheets-advanced 的 `UniverSheetsAdvancedPreset` 预设在运行时依赖 `UniverSheetsDrawingPreset`
> 预设，请先安装 @univerjs/preset-sheets-drawing。

#### npm

```bash
npm install @univerjs/preset-sheets-drawing @univerjs/preset-sheets-advanced
```

#### pnpm

```bash
pnpm add @univerjs/preset-sheets-drawing @univerjs/preset-sheets-advanced
```

#### yarn

```bash
yarn add @univerjs/preset-sheets-drawing @univerjs/preset-sheets-advanced
```

#### bun

```bash
bun add @univerjs/preset-sheets-drawing @univerjs/preset-sheets-advanced
```

### 使用

```typescript
import { UniverSheetsAdvancedPreset } from '@univerjs/preset-sheets-advanced' // [!code ++]
import UniverPresetSheetsAdvancedZhCN from '@univerjs/preset-sheets-advanced/locales/zh-CN' // [!code ++]
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreZhCN from '@univerjs/preset-sheets-core/locales/zh-CN'
import { UniverSheetsDrawingPreset } from '@univerjs/preset-sheets-drawing' // [!code ++]
import UniverPresetSheetsDrawingZhCN from '@univerjs/preset-sheets-drawing/locales/zh-CN' // [!code ++]
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'

import '@univerjs/preset-sheets-core/lib/index.css'
import '@univerjs/preset-sheets-drawing/lib/index.css' // [!code ++]
import '@univerjs/preset-sheets-advanced/lib/index.css' // [!code ++]

const { univerAPI } = createUniver({
  locale: LocaleType.ZH_CN,
  locales: {
    [LocaleType.ZH_CN]: mergeLocales(
      UniverPresetSheetsCoreZhCN,
      UniverPresetSheetsDrawingZhCN, // [!code ++]
      UniverPresetSheetsAdvancedZhCN, // [!code ++]
    ),
  },
  presets: [
    UniverSheetsCorePreset(),
    UniverSheetsDrawingPreset(), // [!code ++]
    UniverSheetsAdvancedPreset(), // [!code ++]
  ],
})
```

如果你拥有 Univer 的商业许可证，请参考[在客户端使用许可证](https://docs.univer.ai/zh-CN/guides/license.md#in-preset-mode)进行配置。

### 预设与配置

```typescript
interface IUniverSheetsAdvancedPresetConfig {
  print?: Partial<IUniverSheetsPrintConfig>
}

interface IUniverSheetsPrintConfig {
  /**
   * 是否强制打印时显示水印
   * @default false
   */
  enforceWatermark?: boolean
}
```

## 插件模式

### 安装

#### npm

```bash
npm install @univerjs-pro/sheets-print
```

#### pnpm

```bash
pnpm add @univerjs-pro/sheets-print
```

#### yarn

```bash
yarn add @univerjs-pro/sheets-print
```

#### bun

```bash
bun add @univerjs-pro/sheets-print
```

### 使用

```typescript
import { UniverSheetsPrintPlugin } from '@univerjs-pro/sheets-print' // [!code ++]
import SheetsPrintPluginZhCN from '@univerjs-pro/sheets-print/locale/zh-CN' // [!code ++]
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'

import '@univerjs-pro/sheets-print/lib/index.css' // [!code ++]

const univer = new Univer({
  locale: LocaleType.ZH_CN,
  locales: {
    [LocaleType.ZH_CN]: mergeLocales(
      SheetsPrintPluginZhCN, // [!code ++]
    ),
  },
})

univer.registerPlugin(UniverSheetsPrintPlugin) // [!code ++]
```

如果你拥有 Univer 的商业许可证，请参考[在客户端使用许可证](https://docs.univer.ai/zh-CN/guides/license.md#in-plugin-mode)进行配置。

### 插件与配置

```typescript
interface IUniverSheetsPrintConfig {
  /**
   * 是否强制打印时显示水印
   * @default false
   */
  enforceWatermark?: boolean
}
```

##

### 引入

```typescript
import '@univerjs-pro/sheets-print/facade'
```

### 打开打印配置对话框

使用 `FWorkbook.openPrintDialog` 可以打开打印配置对话框。

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()

fWorkbook.openPrintDialog()
```

### 关闭打印配置对话框

使用 `FWorkbook.closePrintDialog` 方法可以关闭打印配置对话框。

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
fWorkbook.openPrintDialog()

// 3 秒后关闭打印配置对话框
setTimeout(() => {
  fWorkbook.closePrintDialog()
}, 3000)
```

### 更新打印布局配置

使用 [`FWorkbook.updatePrintConfig(config: ISheetPrintLayoutConfig)`](https://docs.univer.ai/zh-CN/reference/facade/workbook.md#updateprintconfig) 方法更新打印布局配置。

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const subUnitId = fWorksheet.getSheetId()

// 更新打印布局配置
fWorkbook.updatePrintConfig({
  area: univerAPI.Enum.PrintArea.CurrentSheet, // 打印当前工作表
  subUnitIds: [subUnitId],
  paperSize: univerAPI.Enum.PrintPaperSize.A4, // A4 纸张大小
  scale: univerAPI.Enum.PrintScale.FitPage, // 使内容适应页面
  freeze: [univerAPI.Enum.PrintFreeze.Row], // 冻结行标题
  margin: univerAPI.Enum.PrintPaperMargin.Normal, // 正常边距
  // ... 其他设置
})

// 开始打印
fWorkbook.print()
```

#### 以下是 

`ISheetPrintLayoutConfig`

 的完整定义：

```typescript
/**
 * 打印布局设置的配置接口
 */
export interface ISheetPrintLayoutConfig {
  /**
   * 指定要打印的工作表区域（例如，当前工作表，选区）
   */
  area: PrintArea
  /**
   * 要打印的工作簿的工作表 ID 集合，或者包含工作表 ID 和范围的对象集合
   */
  subUnitIds: (string | { id: string, range: IRange })[]
  /**
   * 打印纸张大小设置（例如，A4，信纸）
   */
  paperSize: PrintPaperSize
  /**
   * 打印页面方向（纵向或横向）
   */
  direction: PrintDirection
  /**
   * 打印缩放类型
   */
  scale: PrintScale
  /**
   * 自定义缩放百分比
   */
  customScale: number
  /**
   * 冻结行和列的设置数组
   */
  freeze: PrintFreeze[]
  /**
   * 打印页面的边距预设
   */
  margin: PrintPaperMargin
  /**
   * 使用自定义纸张尺寸时的自定义页面尺寸
   */
  pageSizeCustom?: { w: number, h: number }
  /**
   * 每页打印的最大行数
   */
  maxRowsEachPage: number
  /**
   * 每页打印的最大列数
   */
  maxColumnsEachPage: number
}

/\*\*

- 定义要打印的电子表格区域
_/
export enum PrintArea {
/\*\* 只打印当前活动工作表 _/
CurrentSheet = 'CurrentSheet',
/** 打印整个工作簿 \*/
workbook = 'Workbook',
/** 只打印当前选定的范围 _/
CurrentSelection = 'CurrentSelection',
/\*\* 打印所有选定的范围 _/
AllSelection = 'AllSelection',
}

/\*\*

- 定义打印纸张大小
_/
export enum PrintPaperSize {
/\*\* 使用信纸大小 _/
Letter = 'Letter',
/** 使用小报纸大小 \*/
Tabloid = 'Tabloid',
/** 使用法律纸张大小 _/
Legal = 'Legal',
/\*\* 使用报表纸张大小 _/
Statement = 'Statement',
/** 使用行政公文纸张大小 \*/
Executive = 'Executive',
/** 使用对折纸张大小 _/
Folio = 'Folio',
/\*\* 使用A3纸张大小 _/
A3 = 'A3',
/** 使用A4纸张大小 \*/
A4 = 'A4',
/** 使用A5纸张大小 _/
A5 = 'A5',
/\*\* 使用B4纸张大小 _/
B4 = 'B4',
/\*_ 使用B5纸张大小 _/
B5 = 'B5',
}

/\*\*

- 定义打印页面的方向
_/
export enum PrintDirection {
/\*\* 纵向方向 _/
Portrait = 'Portrait',
/\*_ 横向方向 _/
Landscape = 'Landscape',
}

/\*\*

- 定义打印的缩放类型
_/
export enum PrintScale {
/\*\* 正常缩放 _/
Origin = 'Origin',
/** 适合宽度 \*/
FitWidth = 'FitWidth',
/** 适合高度 _/
FitHeight = 'FitHeight',
/\*\* 适合页面大小 _/
FitPage = 'FitPage',
/\*_ 自定义缩放 _/
Custom = 'Custom',
}

/\*\*

- 定义打印时应保持冻结的元素
_/
export enum PrintFreeze {
/\*\* 打印时保持行标题冻结 _/
Row = 'Row',
/\*_ 打印时保持列标题冻结 _/
Column = 'Column',
}

/\*\*

- 定义打印页面的边距预设
_/
export enum PrintPaperMargin {
/\*\* 使用正常边距 _/
Normal = 'Normal',
/** 使用窄边距 \*/
Narrow = 'Narrow',
/** 使用宽边距 _/
Wide = 'Wide',
/\*\* 没有边距 _/
None = 'None',
}

```

### 更新打印渲染配置

使用 [`FWorkbook.updatePrintRenderConfig(config: ISheetPrintRenderConfig)`](https://docs.univer.ai/zh-CN/reference/facade/workbook.md#updateprintrenderconfig) 方法更新打印渲染配置。

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()

// 更新默认打印布局配置
fWorkbook.updatePrintConfig({})

// 更新打印渲染配置
fWorkbook.updatePrintRenderConfig({
gridlines: true, // 显示网格线
hAlign: univerAPI.Enum.PrintAlign.Middle, // 水平居中对齐
vAlign: univerAPI.Enum.PrintAlign.Middle, // 垂直居中对齐
headerFooter: [ // 要包含的页眉和页脚元素数组，这里是页码和工作表名称
  univerAPI.Enum.PrintHeaderFooter.PageSize,
  univerAPI.Enum.PrintHeaderFooter.WorksheetTitle,
],
// ... 其他设置
})

// 开始打印
fWorkbook.print()
```

#### 以下是 

`ISheetPrintRenderConfig`

 的完整定义：

```typescript
/**
 * 打印渲染选项的配置接口
 */
export interface ISheetPrintRenderConfig {
  /**
   * 是否在打印输出中显示网格线
   */
  gridlines: boolean
  /**
   * 水平对齐设置
   */
  hAlign: PrintAlign
  /**
   * 垂直对齐设置
   */
  vAlign: PrintAlign
  /**
   * 包含的页眉和页脚元素数组
   */
  headerFooter: PrintHeaderFooter[]
  /**
   * 页眉和页脚的详细设置
   */
  headerFooterSetting: IPrintHeaderFooter
  /**
   * 是否使用自定义页眉和页脚而不是预设
   */
  isCustomHeaderFooter?: boolean

  watermark?: Nullable<IWatermarkConfigWithType>

}

/\*\*

- 定义打印内容的可用对齐选项
_/
export enum PrintAlign {
/\*\* 水平方向左对齐，垂直方向顶部对齐 _/
Start = 'Start',
/** 水平方向右对齐，垂直方向底部对齐 \*/
End = 'End',
/** 水平方向居中对齐，垂直方向居中对齐 \*/
Middle = 'Middle',
}

/\*\*

- 定义页眉和页脚内容的可用占位符
_/
export enum PrintHeaderFooter {
/\*\* 插入当前页码信息 _/
PageSize = 'PageSize',
/** 插入工作簿名称 \*/
WorkbookTitle = 'WorkbookTitle',
/** 插入工作表名称 _/
WorksheetTitle = 'WorksheetTitle',
/\*\* 插入当前日期 _/
Date = 'Date',
/\*_ 插入当前时间 _/
Time = 'Time',
}

/\*\*

- 页眉和页脚内容定位的配置接口
_/
export interface IPrintHeaderFooter {
/\*\* 左上角显示的内容 _/
topLeft: string
/** 顶部中心显示的内容 \*/
topCenter: string
/** 右上角显示的内容 _/
topRight: string
/\*\* 左下角显示的内容 _/
bottomLeft: string
/** 底部中心显示的内容 \*/
bottomCenter: string
/** 右下角显示的内容 \*/
bottomRight: string
}

```

### 调起打印

使用 `FWorkbook.print` 方法可以直接调起打印。

```typescript
// 使用默认配置可以传入空对象
workbook.updatePrintConfig({
// ... 打印布局配置
})
workbook.updatePrintRenderConfig({
// ... 打印渲染配置
})
workbook.print()
```

### 保存截图至剪贴板

使用 `FWorkbook.saveScreenshotToClipboard` 方法可以保存打印数据图片到剪切板。

该 API 仅在拥有 [许可证](https://docs.univer.ai/zh-CN/guides/license.md) 的情况下可用，未持有许可证时将受到使用限制，保存操作将返回 `false`。

我们使用 Clipboard API 保存图片到剪贴板，在非安全网络环境或某些不支持的浏览器可能会保存失败。保存成功会返回 `true`。

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const result = await fWorkbook.saveScreenshotToClipboard()
```

### 获取选区截图

使用 `FRange.getScreenshot` 方法可以获取选区打印数据图片。

该 API 仅在持有 [许可证](https://docs.univer.ai/zh-CN/guides/license.md) 时可用，未持证用户将受到使用限制，保存失败时返回 `false`，成功时返回图片的 base64 字符串。

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:D10')
fRange.getScreenshot()
fRange.getScreenshot({ includeHeaders: true }) // 包含行列标题
```

### 事件监听

完整事件类型定义，请查看 [Events](https://docs.univer.ai/zh-CN/reference/facade/events.md)。

`univerAPI.Event.BeforeSheetPrintOpen` 事件在打开打印配置对话框之前触发。

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetPrintOpen, (params) => {
  const { workbook, worksheet } = params

  // 取消打开打印配置对话框操作
  params.cancel = true
})

// 移除事件监听器，使用 `disposable.dispose()`
```

`univerAPI.Event.SheetPrintOpen` 事件在打开打印配置对话框之后触发。

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.SheetPrintOpen, (params) => {
  const { workbook, worksheet } = params
})

// 移除事件监听器，使用 `disposable.dispose()`
```

`univerAPI.Event.BeforeSheetPrintConfirm` 事件在确认打印之前触发。

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetPrintConfirm, (params) => {
  const { renderConfig, layoutConfig } = params

  // 取消打印确认操作
  params.cancel = true
})

// 移除事件监听器，使用 `disposable.dispose()`
```

`univerAPI.Event.SheetPrintConfirmed` 事件在确认打印之后触发。

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.SheetPrintConfirmed, (params) => {
  const { renderConfig, layoutConfig } = params
})

// 移除事件监听器，使用 `disposable.dispose()`
```

`univerAPI.Event.BeforeSheetPrintCanceled` 事件在取消打印之前触发。

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetPrintCanceled, (params) => {
  const { renderConfig, layoutConfig } = params

  // 取消打印取消操作
  params.cancel = true
})

// 移除事件监听器，使用 `disposable.dispose()`
```

`univerAPI.Event.SheetPrintCanceled` 事件在取消打印之后触发。

```typescript
const disposable = univerAPI.addEvent(univerAPI.Event.SheetPrintCanceled, (params) => {
  const { renderConfig, layoutConfig } = params
})

// 移除事件监听器，使用 `disposable.dispose()`
```
