gpt4 book ai didi

excel - 使用 ReportViewer 内置功能导出到 Excel

转载 作者:行者123 更新时间:2023-12-01 02:31:08 24 4
gpt4 key购买 nike

我想知道是否可以将 Excel 输出设置为“锁定”,因为当我们尝试更改单元格的值时,会出现警告,表明我们无法更改它,除非我们删除表的保护。

我知道我们可以开发自定义 Excel 自动化代码,并在保存工作表之前设置密码来保护工作表。但是,有没有什么简单的方法可以使用 ReportViewer 的内置功能来实现这一点?

最佳答案

经过一番研究,我设法找到了解决方案:)
思路是截取ReportViewer的Export Report函数,然后运行我们自己的进程。此过程将获得正在生成的 Excel 文件的输出,然后读取它并应用任何必要的更改,并在将其作为下载发送给用户之前再次保存。
但是应该注意的是,拦截方法会根据我们使用的报告类型而有所不同。就我而言,我的 ReportViewer 使用的是 WebForm 而不是 WinForm,并且大多数解释都是关于 ReportExport 事件的解释,该事件仅在 WinForm 中可用。

对于使用 WinForm 的用户,您可以像这样覆盖 ReportExport 事件:

void reportViewer_ReportExport(object sender, Microsoft.Reporting.WinForms.ReportExportEventArgs e)
{
e.Cancel = true;
// insert your own code to export excel
}

在 WebForm 中,没有 ReportExport 的事件处理程序。我能想到的选项是在 .aspx 中创建一个自定义按钮,它将执行我们的自定义代码,或者直接呈现 excel 而无需预览报告。
我决定直接渲染excel文件。我将使用数据集并从存储过程中获取数据。然后,我将数据集分配给 RDLC 并调用 Render 方法来获取输出。输出格式为byte[],我用FileStream来写。完成后,我使用 Interop 打开 Excel 文件并应用保护。这是代码:

// Setup DataSet (Adapter and Table)
YourTableAdapters.ATableAdapter ds = new YourTableAdapters.ATableAdapter();
YourDataSet.ADataTable dt = new YourDataSet.ADataTable ();

ds.Fill(dt, outlet, period);

// Create Report DataSource
ReportDataSource rds = new ReportDataSource("DataSet1", (System.Data.DataTable)dt);

// Variables needed for ReportViewer Render method
Warning[] warnings;
string[] streamIds;
string mimeType = string.Empty;
string encoding = string.Empty;
string extension = string.Empty;

// Setup the report viewer object and get the array of bytes
ReportViewer viewer = new ReportViewer();
viewer.ProcessingMode = ProcessingMode.Local;
viewer.LocalReport.ReportPath = "YourReport.rdlc";
viewer.LocalReport.DataSources.Add(rds); // Add datasource here

byte[] bytes = viewer.LocalReport.Render("Excel", null, out mimeType,
out encoding, out extension,
out streamIds, out warnings);

// Prepare filename and save_path, and then write the Excel using FileStream.
String temp_path = Path.Combine(Server.MapPath(Config.ReportPath), "FileName.xls");
FileStream fs = new FileStream(temp_path, FileMode.Create);
fs.Write(bytes, 0, bytes.Length);
fs.Close();

// Open the Excel file created, and add password protection.
PIDExcel pidexcel = new PIDExcel();
pidexcel.CollectExcelPID();

Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Range lock_range = null;

int excelid = pidexcel.GetNewExcelID();

Microsoft.Office.Interop.Excel.Workbook xlWorkBook = null;

try
{
//xlApp.Visible = true;
xlWorkBook = (Microsoft.Office.Interop.Excel.Workbook)xlApp.Workbooks.Open(temp_path,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);

foreach(Microsoft.Office.Interop.Excel.Worksheet displayWorksheet in xlApp.ActiveWorkbook.Worksheets)
{
lock_range = xlApp.Cells;
lock_range.Select();
lock_range.EntireColumn.Locked = true;
displayWorksheet.Protect("<your password here>");
}

}
catch (Exception ex)
{
throw new Exception(ex.Message.Replace("'", "")); ;
}
finally
{
// Set First Sheet Active
xlWorkBook.Sheets[1].Select();
xlApp.DisplayAlerts = false;
xlWorkBook.Save();
xlWorkBook.Close(Type.Missing, Type.Missing, Type.Missing);
xlApp.Quit();

System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlWorkBook);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp);

GC.WaitForPendingFinalizers();
GC.Collect();

pidexcel.KillExcel(excelid);

}

通过使用这个概念,我可以轻松地设计报表输出,因为我使用 RDLC 作为模板来填充 SP 提供的数据,然后进行渲染。想象一下,如果我们使用 Excel 手动编码报表(设置边框、合并单元格、分组),将会有多么麻烦。

关于excel - 使用 ReportViewer 内置功能导出到 Excel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12241736/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com