# dotNet.ReoGrid 扩展库 - ReoGrid 分页与打印功能

自动分页
--------------------

当工作表需要打印时，ReoGrid会自动执行分页操作。分页过程会扫描工作表，并根据分页设置决定每页的打印范围。例如下图展示了一个垂直分页的工作表：

![108](../images/108.png)

与Excel类似，ReoGrid会计算每页能容纳的最大单元格数量，无法完整打印的单元格会自动移至下一页：

![109](../images/109.png)

执行自动分页或重置分页符
------------------------------------------------

任何时候都可以执行自动分页或重置当前分页符：

```aardio
sheet1.AutoSplitPage();
```

该方法执行速度极快（<10ms），但如果默认打印机是网络打印机，获取纸张尺寸可能会耗时超过100ms（取决于网络环境）。

显示分页线
------------------------

要在屏幕上显示分页线：

```aardio
sheet1.EnableSettings(ReoGrid.WorksheetSettings.View_ShowPageBreaks);
```

效果：![120](../images/120.png)

自动检测可打印边界
----------------------------------------

如果未指定打印范围，ReoGrid会自动检测已使用的单元格区域作为打印范围：

![121](../images/121.png)

修改打印范围
---------------------------

通过工作表的`PrintableRange`属性可以修改打印范围：

```aardio
// 构造参数为(行,列,行数,列数)
sheet1.PrintableRange = ReoGrid.RangePosition(1, 1, 9, 9);
```

![122](../images/122.png)

如果打印范围超过纸张尺寸，会自动分页。超出打印范围的单元格不会被打印。

修改分页顺序
---------------------------

通过`PrintSettings.PageOrder`属性可以修改分页方向：

![112](../images/1121.png)

```aardio
// 设置分页顺序为"先下后右"
sheet1.PrintSettings.PageOrder = ReoGrid.PrintPageOrder.DownThenOver;
```

修改页面设置
---------------------------

通过工作表的`PrintSettings`属性可以修改纸张设置：

```aardio
// 设置为横向打印
sheet1.PrintSettings.Landscape = true;
// 设置页边距为5个单位
sheet1.PrintSettings.Margins = ReoGrid.PageMargins(5);
```

示例：横向自动分页效果：

![123](../images/123.png)

打印缩放
--------------------

通过`PrintSettings.PageScaling`属性可以设置打印缩放比例：

```aardio
// 缩放至70%
sheet1.PrintSettings.PageScaling = 0.7;
```

修改缩放比例后，工作表会自动重新分页。

插入分页符
------------------------

通过工作表的`RowPageBreaks`和`ColumnPageBreaks`属性可以插入分页符：

```aardio
// 在第5列插入垂直分页符
sheet1.ColumnPageBreaks.Add(5);
```

表格被分割为两页：

![124](../images/124.png)

用户分页符与系统分页符
--------------------------------------------

分页符有两种类型：实线表示用户分页符（通过`AutoSplitPage`方法或用户操作生成）；虚线表示系统分页符（由ReoGrid自动插入）：

![125](../images/125.png)

修改分页符
------------------------

要修改分页符位置（无论是系统还是用户分页符），可以使用以下方法：

```aardio
// 修改列分页符位置
sheet1.ChangeColumnPageBreak(旧位置, 新位置);
// 修改行分页符位置
sheet1.ChangeRowPageBreak(旧位置, 新位置);
```

分页符被修改后将变为用户分页符，不再由ReoGrid自动更新。

遍历打印页
------------------------

通过工作表的`IteratePrintPages`方法可以遍历所有打印页，该方法返回每页的范围：

```aardio
sheet1.IteratePrintPages( function(range){
    console.log("页面范围：" ++ range.ToAddress());
    return true;
});
```

输出示例：
```
页面范围：A1:E11
页面范围：F1:K11
```

可以指定遍历顺序：

```aardio
sheet1.IteratePrintPages(
    ReoGrid.PrintPageOrder.OverThenDown, 
    function(range){
        // 处理逻辑
    }
);
```

如未指定顺序，则使用打印设置中的分页顺序。

禁止用户修改分页符
--------------------------------------

要禁止用户通过鼠标调整分页符位置：

```aardio
sheet1.SetSettings(
    ReoGrid.WorksheetSettings.Behavior_AllowUserChangingPageBreaks, 
    false
);
```

打印会话
--------------------

打印会话用于打印整个工作簿或指定工作表。打印整个工作簿或多个工作表时，从控件实例创建工作簿打印会话；打印单个工作表时，从该工作表创建会话。

![263](../images/263.png)

### 打印单个工作表

```aardio
var session = sheet1.CreatePrintSession();
session.Print();
```

### 打印整个工作簿

```aardio
var session = reoGridControl.CreatePrintSession();
session.Print();
```

### 打印指定工作表

```aardio
var session = reoGridControl.CreatePrintSession();
session.Worksheets.Clear();
session.Worksheets.Add(grid.Worksheets["Sheet1"]);
session.Worksheets.Add(grid.Worksheets["Sheet3"]);
session.Print();
```

打印预览
--------------------

以下代码显示标准.NET打印预览对话框：

```aardio
var sheet1 = reoGridControl.CurrentWorksheet;
var session = sheet1.CreatePrintSession();
try {
    import System.Windows.Forms;
    var ppd = System.Windows.Forms.PrintPreviewDialog();
    ppd.Document = session.PrintDocument;
    ppd.SetBounds(200, 200, 1024, 768);
    ppd.PrintPreviewControl.Zoom = 1.0;
    ppd.ShowDialog(winform);
}
finally {
    session.Dispose();
}
```

直接打印
--------------------

使用默认设置打印工作表：

```aardio
var session = sheet1.CreatePrintSession();
session.Print();
```

通过标准打印对话框打印
------------------------------------------

显示标准打印对话框后打印指定工作表：

```aardio
import System.Windows.Forms;
var doc = null;
try {
    doc = sheet1.CreatePrintSession().PrintDocument;
    var pd = System.Windows.Forms.PrintDialog();
    pd.Document = doc;
    pd.UseEXDialog = true;  // 64位Windows系统
    if(pd.ShowDialog(winform) == System.Windows.Forms.DialogResult.OK) {
        doc.PrinterSettings = pd.PrinterSettings;
        doc.Print();
    }
}
catch(e) {
    win.msgbox(e.message, "打印错误");
}
finally {
    if(doc) doc.Dispose();
}
```

显示系统页面设置对话框
--------------------------------------------

```aardio
import System.Windows.Forms;
var psd = System.Windows.Forms.PageSetupDialog();
try {
    // 将ReoGrid页面设置转换为系统页面设置
    psd.PageSettings = sheet1.PrintSettings.CreateSystemPageSettings();
    psd.AllowMargins = true;
    psd.AllowPrinter = true;
    psd.AllowPaper = true;
    psd.EnableMetric = true;
    
    if(psd.ShowDialog(winform) == System.Windows.Forms.DialogResult.OK) {
        // 将系统设置转换回ReoGrid设置
        sheet1.PrintSettings.ApplySystemPageSettings(psd.PageSettings);
    }
}
finally {
    psd.Dispose();
}
```

附：unvell.ReoGrid.Print.PrintSettings 的 C# 源码中公开的属性如下：

```cs
namespace unvell.ReoGrid.Print;

public class PrintSettings : ICloneable{
	public string PrinterName { get; set; }
	public PrintPageOrder PageOrder { get; set; }
	public bool ShowMargins { get; set; }
	public bool ShowGridLines { get; set; }
	public float PageScaling { get; set; }
	public string PaperName { get; set; }
	public bool Landscape { get; set; }
	public float PaperWidth { get; set; }
	public float PaperHeight { get; set; }
	public PageMargins Margins { get; set; }
}
```