第八章:打印与导出
前言欢迎来到第八章经过前面七章的学习你的 Spread 表格已经具备了数据展示、美化、计算、交互、数据处理等完整功能。但还有一个最常见的需求用户想把表格打印出来或者导出为 Excel/PDF 文件。今天我们就来学习 FpSpread 的打印与导出功能。学完这一章你的表格将真正具备“企业级交付”能力。一、打印基础1.1 最简单的打印一行代码就能调出打印对话框csharp// 弹出打印对话框用户确认后打印 fpSpread1.PrintSheet(0); // 0 表示打印第一个 Sheet1.2 静默打印无对话框csharp// 不弹出任何对话框直接发送到默认打印机 PrintInfo printInfo new PrintInfo(); printInfo.PrintToPrinter true; printInfo.ShowDialog false; // 不显示对话框 fpSpread1.SetPrintInfo(printInfo, 0); fpSpread1.PrintSheet(0);1.3 打印预览csharp// 显示打印预览窗口 fpSpread1.PrintPreview(0);二、打印设置PrintInfoPrintInfo对象提供了丰富的打印配置选项。2.1 基本设置csharpPrintInfo printInfo new PrintInfo(); // 纸张设置 printInfo.PaperSize new System.Drawing.Printing.PaperSize(A4, 827, 1169); printInfo.Landscape false; // 横向打印true横向false纵向 printInfo.Margin new PrintMargin(50, 50, 50, 50); // 上、左、下、右单位1/100英寸 // 打印范围 printInfo.PrintType PrintType.All; // 打印所有页其他选项CellRange、Selection、VisibleRows // 打印质量 printInfo.PrintQuality PrintQuality.High; // 打印份数 printInfo.Copies 2; // 应用设置 fpSpread1.SetPrintInfo(printInfo, 0); fpSpread1.PrintSheet(0);2.2 页眉和页脚csharpPrintInfo printInfo new PrintInfo(); // 页眉居左、居中、居右用 \t 分隔 printInfo.Header 公司机密\t销售报表\t打印日期{Date}; // 页脚 printInfo.Footer 第 {Page} 页 / 共 {PageCount} 页\t\t制表人管理员; // 页眉/页脚字体 printInfo.HeaderFont new Font(微软雅黑, 9, FontStyle.Bold); printInfo.FooterFont new Font(宋体, 8); // 页眉/页脚高度 printInfo.HeaderHeight 40; printInfo.FooterHeight 30; fpSpread1.SetPrintInfo(printInfo, 0);页眉/页脚支持的变量变量说明示例输出{Date}当前日期2024-01-15{Time}当前时间14:30:25{Page}当前页码1{PageCount}总页数5{SheetName}工作表名称Sheet12.3 缩放与自适应csharpPrintInfo printInfo new PrintInfo(); // 缩放到一页宽 printInfo.ZoomFactor 0; // 0 表示自动适应 printInfo.ZoomToFit true; // 自动适应页面宽度 // 手动设置缩放比例如 80% printInfo.ZoomFactor 80; // 百分比 printInfo.ZoomToFit false; // 打印整个工作表在一页内 printInfo.ZoomToFit true; printInfo.BestFitToWide 1; // 适应宽度 printInfo.BestFitToTall 1; // 适应高度 fpSpread1.SetPrintInfo(printInfo, 0);2.4 网格线与边框csharpPrintInfo printInfo new PrintInfo(); // 打印网格线 printInfo.PrintGrid true; printInfo.PrintGridLineColor Color.LightGray; // 打印行头/列头默认 true printInfo.PrintRowHeader true; printInfo.PrintColumnHeader true; // 打印背景色/图片默认 true printInfo.PrintBackground true; // 打印颜色黑白/彩色 printInfo.PrintColor true; // true彩色false黑白 fpSpread1.SetPrintInfo(printInfo, 0);2.5 重复打印标题行/列多页打印时让标题行在每一页都出现csharpPrintInfo printInfo new PrintInfo(); // 重复打印第 0-2 行表头在每一页顶部都打印 printInfo.RepeatRowStart 0; printInfo.RepeatRowEnd 2; // 重复打印第 0 列第一列在每一页左侧都打印 printInfo.RepeatColStart 0; printInfo.RepeatColEnd 0; fpSpread1.SetPrintInfo(printInfo, 0);2.6 分页控制csharp// 在指定行之前插入分页符 fpSpread1.Sheets[0].SetRowPageBreak(20, true); // 在第20行前分页 // 在指定列之前插入分页符 fpSpread1.Sheets[0].SetColumnPageBreak(5, true); // 在第5列前分页 // 取消分页符 fpSpread1.Sheets[0].SetRowPageBreak(20, false); fpSpread1.Sheets[0].ClearRowPageBreaks();三、导出 Excel3.1 基础导出csharp// 保存为 Excel 文件 fpSpread1.SaveExcel(C:\\报表.xlsx, FarPoint.Excel.ExcelSaveFlags.SaveCustomColumnHeaders); // 保存为 Excel 97-2003 格式.xls fpSpread1.SaveExcel(C:\\报表.xls, FarPoint.Excel.ExcelSaveFlags.SaveCustomColumnHeaders);3.2 带对话框的导出csharpprivate void btnExport_Click(object sender, EventArgs e) { SaveFileDialog sfd new SaveFileDialog(); sfd.Filter Excel文件|*.xlsx|Excel 97-2003|*.xls; sfd.FileName $报表_{DateTime.Now:yyyyMMdd}; if (sfd.ShowDialog() DialogResult.OK) { FarPoint.Excel.ExcelSaveFlags flags FarPoint.Excel.ExcelSaveFlags.SaveCustomColumnHeaders; // 根据扩展名决定保存格式 if (sfd.FileName.EndsWith(.xls)) flags | FarPoint.Excel.ExcelSaveFlags.SaveAsFiltered; // 保存为旧格式 fpSpread1.SaveExcel(sfd.FileName, flags); MessageBox.Show(导出成功, 提示, MessageBoxButtons.OK, MessageBoxIcon.Information); } }3.3 导出选项详解csharp// 多种导出标志的组合使用 FarPoint.Excel.ExcelSaveFlags flags FarPoint.Excel.ExcelSaveFlags.SaveCustomColumnHeaders | // 保存自定义列头 FarPoint.Excel.ExcelSaveFlags.SaveAsFiltered | // 保存为筛选格式 FarPoint.Excel.ExcelSaveFlags.UseOOXMLFormat | // 使用 OpenXML 格式.xlsx FarPoint.Excel.ExcelSaveFlags.NoTotals; // 不导出汇总行 // 只导出当前筛选后的数据 flags | FarPoint.Excel.ExcelSaveFlags.ExportAsFiltered; // 不导出公式只导出值 flags | FarPoint.Excel.ExcelSaveFlags.DataOnly; fpSpread1.SaveExcel(C:\\报表.xlsx, flags);常用 ExportFlags标志说明SaveCustomColumnHeaders保存自定义列头SaveAsFiltered保存为筛选格式.xlsUseOOXMLFormat使用 .xlsx 格式DataOnly只保存数据不保存公式NoFormulas不保存公式NoNotes不保存批注ExportAsFiltered只导出筛选后的行四、导出 PDF4.1 基础 PDF 导出csharp// 安装需引入 FarPoint.Win.Spread.dll导出为 PDF fpSpread1.SavePdf(C:\\报表.pdf, 0); // 0 表示第一个 Sheet // 保存所有 Sheet 到一个 PDF fpSpread1.SavePdf(C:\\全部报表.pdf);4.2 PDF 打印设置csharp// 创建 PDF 专用的 PrintInfo PrintInfo printInfo new PrintInfo(); printInfo.PrintType PrintType.All; printInfo.Landscape true; // 横向 printInfo.ZoomToFit true; // 适应页面宽度 printInfo.Header 公司销售报表; printInfo.Footer 第 {Page} 页 / 共 {PageCount} 页; // 应用设置 fpSpread1.SetPrintInfo(printInfo, 0); // 导出 PDF使用设置 fpSpread1.SavePdf(C:\\报表.pdf, 0);4.3 带对话框的 PDF 导出csharpprivate void btnExportPDF_Click(object sender, EventArgs e) { SaveFileDialog sfd new SaveFileDialog(); sfd.Filter PDF文件|*.pdf; sfd.FileName $报表_{DateTime.Now:yyyyMMdd}; if (sfd.ShowDialog() DialogResult.OK) { // 可选的 PDF 导出设置 // 1. 设置质量默认值 300 fpSpread1.PdfExportQuality 200; // 2. 导出 fpSpread1.SavePdf(sfd.FileName, 0); MessageBox.Show(PDF 导出成功); // 3. 询问是否打开 if (MessageBox.Show(是否立即打开, 提示, MessageBoxButtons.YesNo) DialogResult.Yes) { System.Diagnostics.Process.Start(sfd.FileName); } } }五、导出 CSV 和 HTML5.1 导出 CSVcsharp// 保存为 CSV逗号分隔 fpSpread1.SaveText(C:\\数据.csv, TextFileFlags.ExportHeaders); // 保存为其他分隔符 fpSpread1.SaveText(C:\\数据.txt, TextFileFlags.ExportHeaders, null, \t); // Tab分隔 // 导出时包含/排除列头 TextFileFlags flags TextFileFlags.ExportHeaders | TextFileFlags.ExportFormulas; fpSpread1.SaveText(C:\\数据.csv, flags);5.2 导出 HTMLcsharp// 保存整个 Sheet 为 HTML fpSpread1.SaveHtml(C:\\报表.html, 0); // 0 表示第一个 Sheet // 保存单个区域为 HTML fpSpread1.SaveHtml(C:\\区域.html, new CellRange(0, 0, 10, 5)); // 保存所有 Sheet 到一个 HTML 文件 fpSpread1.SaveHtml(C:\\全部报表.html, true); // true 表示所有 Sheet六、打印/导出的事件6.1 打印前/后事件csharp// 开始打印 fpSpread1.PrintMessageBoxShowing (sender, e) { e.MessageBox new FpPrintMessageBox(); e.MessageBox.Message 正在准备打印请稍后...; }; // 打印进度 fpSpread1.PrintProgress (sender, e) { Console.WriteLine($打印进度{e.Percent}%); progressBar1.Value e.Percent; }; // 打印完成 fpSpread1.PrintSheetComplete (sender, e) { if (e.Error ! null) MessageBox.Show($打印出错{e.Error.Message}); else MessageBox.Show(打印完成); };6.2 导出事件csharp// 导出 Excel 前可以进行最后的数据处理 fpSpread1.SaveExcelStarting (sender, e) { // 在导出前执行一些操作如隐藏某些列 fpSpread1.Sheets[0].Columns[5].Visible false; }; // 导出 Excel 完成 fpSpread1.SaveExcelCompleted (sender, e) { Console.WriteLine($导出完成文件{e.FileName}); };七、完整示例报表中心csharppublic partial class ReportForm : Form { public ReportForm() { InitializeComponent(); LoadReportData(); } private void LoadReportData() { // 模拟加载销售报表 SheetView sheet fpSpread1.Sheets[0]; // 设置列头 sheet.ColumnHeader.Cells[0, 0].Text 月份; sheet.ColumnHeader.Cells[0, 1].Text 销售额; sheet.ColumnHeader.Cells[0, 2].Text 成本; sheet.ColumnHeader.Cells[0, 3].Text 利润; sheet.ColumnHeader.Cells[0, 4].Text 利润率; // 填充测试数据 string[] months { 1月, 2月, 3月, 4月, 5月, 6月 }; Random rnd new Random(); for (int i 0; i months.Length; i) { sheet.Cells[i, 0].Value months[i]; sheet.Cells[i, 1].Value rnd.Next(80, 150) * 10000; sheet.Cells[i, 2].Value rnd.Next(50, 100) * 10000; sheet.Cells[i, 3].Formula $B{i2}-C{i2}; sheet.Cells[i, 4].Formula $D{i2}/B{i2}; // 设置利润率格式为百分比 PercentCellType percentType new PercentCellType(); percentType.DecimalPlaces 1; sheet.Cells[i, 4].CellType percentType; } // 统计行 sheet.Rows.Add(months.Length, 1); int sumRow months.Length; sheet.Cells[sumRow, 0].Value 合计; sheet.Cells[sumRow, 1].Formula $SUM(B2:B{sumRow}); sheet.Cells[sumRow, 2].Formula $SUM(C2:C{sumRow}); sheet.Cells[sumRow, 3].Formula $D{sumRow}1; } // 打印预览 private void btnPrintPreview_Click(object sender, EventArgs e) { SetPrintSettings(); fpSpread1.PrintPreview(0); } // 直接打印 private void btnPrint_Click(object sender, EventArgs e) { SetPrintSettings(); fpSpread1.PrintSheet(0); } // 打印设置 private void SetPrintSettings() { PrintInfo printInfo new PrintInfo(); // 页眉页脚 printInfo.Header 公司月度销售报表\t\t{Date}; printInfo.Footer 第 {Page} 页 / 共 {PageCount} 页; // 缩放 printInfo.ZoomToFit true; // 重复标题行 printInfo.RepeatRowStart 0; printInfo.RepeatRowEnd 0; // 边距 printInfo.Margin new PrintMargin(50, 50, 50, 50); fpSpread1.SetPrintInfo(printInfo, 0); } // 导出 Excel private void btnExportExcel_Click(object sender, EventArgs e) { SaveFileDialog sfd new SaveFileDialog(); sfd.Filter Excel文件|*.xlsx; sfd.FileName $销售报表_{DateTime.Now:yyyyMMdd}; if (sfd.ShowDialog() DialogResult.OK) { FarPoint.Excel.ExcelSaveFlags flags FarPoint.Excel.ExcelSaveFlags.SaveCustomColumnHeaders | FarPoint.Excel.ExcelSaveFlags.UseOOXMLFormat; fpSpread1.SaveExcel(sfd.FileName, flags); MessageBox.Show(导出成功, 提示); if (MessageBox.Show(是否打开文件, 提示, MessageBoxButtons.YesNo) DialogResult.Yes) { System.Diagnostics.Process.Start(sfd.FileName); } } } // 导出 PDF private void btnExportPDF_Click(object sender, EventArgs e) { SaveFileDialog sfd new SaveFileDialog(); sfd.Filter PDF文件|*.pdf; sfd.FileName $销售报表_{DateTime.Now:yyyyMMdd}; if (sfd.ShowDialog() DialogResult.OK) { // 复用打印设置 SetPrintSettings(); fpSpread1.PdfExportQuality 200; fpSpread1.SavePdf(sfd.FileName, 0); MessageBox.Show(PDF 导出成功); } } // 导出 CSV private void btnExportCSV_Click(object sender, EventArgs e) { SaveFileDialog sfd new SaveFileDialog(); sfd.Filter CSV文件|*.csv; sfd.FileName $销售报表_{DateTime.Now:yyyyMMdd}; if (sfd.ShowDialog() DialogResult.OK) { fpSpread1.SaveText(sfd.FileName, TextFileFlags.ExportHeaders); MessageBox.Show(CSV 导出成功); } } }八、常见问题Q1打印出来和屏幕显示不一样A检查PrintInfo中的ZoomToFit、BestFitToWide、BestFitToTall设置。Q2导出的 Excel 文件很大A尝试使用ExportAsFiltered标志或只导出需要的数据区域。Q3PDF 导出中文乱码A需要在PrintInfo中设置支持中文的字体csharpprintInfo.HeaderFont new Font(微软雅黑, 10); printInfo.FooterFont new Font(微软雅黑, 9);Q4导出图片/图表到 ExcelAFpSpread 原生支持导出图表只要在 Spread 中添加了图表控件导出到 Excel 时会自动保留。本章小结今天我们学了功能关键代码常用场景打印预览PrintPreview()用户确认格式后再打印直接打印PrintSheet()静默打印不弹对话框打印设置PrintInfo页眉页脚、缩放、重复标题Excel 导出SaveExcel()用户需要编辑报表PDF 导出SavePdf()不可编辑的最终交付件CSV 导出SaveText()数据交换、导入其他系统HTML 导出SaveHtml()网页展示