导出到Excel中使用的ReportViewer内置功能(Export to Excel using

2019-09-22 02:20发布

我想知道是否可以设置输出到Excel为“锁定”,在这个意义上,当我们试图改变一个单元格的值,那么就会出现表明我们不能改变它,除非我们删除了警告表的保护。

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

Answer 1:

之后做一些研究,我已经成功地找到解决方案:)这个想法是拦截的ReportViewer的导出报表功能,并运行自己的进程。 这个过程会得到输出正在产生的Excel文件,然后阅读并应用任何必要的修改,然后再次保存之前它是作为下载到用户发送。 但是,应该指出的是,基于什么样的,我们使用报告的拦截方法会有所不同。 就我而言,在那里被解释有关ReportExport事件,仅在现有的WinForm的ReportViewer我使用的WebForm,而不是WinForm中,大多数的解释。

对于使用WinForm的那些,可以覆盖这样的ReportExport事件:

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

在Web窗体,有ReportExport没有事件处理程序。 我能想到的方案正在创建的.aspx自定义按钮,将执行我们的自定义代码,或直接呈现在Excel中,而无需预览报告。 我决定直接呈现在Excel文件。 我将使用一个数据集,并从存储过程获取数据。 然后,我分配到的数据集和RDLC调用Render方法来获取输出。 输出格式是在字节[],并且我使用的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的报告(地设置边框,合并单元格,分组)。



文章来源: Export to Excel using ReportViewer built-in feature