2009-08-31 46 views
11

Trong ứng dụng C# của tôi, tôi đang sử dụng chuỗi kết nối OLEDB "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\test.xls;Extended Properties=\"Excel 8.0;HDR=NO;ReadOnly=true;IMEX=1\"" để đọc các tệp Excel. Để đọc tệp được bảo vệ bằng mật khẩu, tôi đã thử thêm trường mật khẩu trong chuỗi kết nối nhưng không thể đọc tệp. Tôi muốn biết là có cách nào để đọc các tệp Excel được bảo vệ bằng mật khẩu bằng OLEDB nếu tôi biết mật khẩu của nó trước đó.Đọc tệp excel được bảo vệ bằng mật khẩu bằng OLEDB trong C#

+2

PWD = mật khẩu Bạn đã thử? – Havenard

Trả lời

5

Dưới đây là different ways to connect to an Excel file, bao gồm OLEDB. Theo đó, bạn không thể mở tệp được bảo vệ bằng mật khẩu bằng các phương thức chuẩn. Bạn phải sử dụng giải pháp thay thế.

Nếu bảng tính Excel được bảo vệ bởi một mật khẩu, bạn không thể mở nó cho truy cập dữ liệu, thậm chí bằng cách cung cấp các mật khẩu chính xác với chuỗi kết nối của bạn. Nếu bạn cố gắng, bạn sẽ nhận được thông báo lỗi sau: "Không thể tập giải mã

This is the solution, mặc dù không phải trong C#, nhưng bạn có thể dễ dàng thích nghi với nó cho mục đích của bạn

Nếu bạn don'.. t bIẾT mật khẩu cho mình, một sự thay thế là để viết lại các tập tin mà không có một mật khẩu Bạn có thể sử dụng this handy project và thêm các thói quen sau đây với nó:..

public void SaveFile() 

     { 
      this.excelWorkbook.SaveAs(
       this.excelWorkbook.FullName, 
       vk_format, 
       "", 
       vk_write_res_password, 
       vk_read_only, 
       null, 
       Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, 
       null, 
       vk_add_to_mru, 
       null,null,vk_local); 
     } 

Full detail here

2

Bạn có thể sử dụng OoXmlCrypto stream để truy cập các tệp được mã hóa Office 2007. Mã nguồn mở, bao gồm ExcelPackage đã sửa đổi.

Mẫu mã:

using (OfficeCryptoStream stream = OfficeCryptoStream.Open("a.xlsx", "password")) 
{ 
    // Do stuff (e.g. create System.IO.Packaging.Package or 
    // ExcelPackage from the stream, make changes and save) 

    // Change the password (optional) 
    stream.Password = "newPassword"; 

    // Encrypt and save the file 
    stream.Save(); 
} 
5

Nếu bạn sử dụng một truy vấn để đọc file excel, nó không quan trọng nếu một số tờ được bảo vệ: Nó hoạt động một trong hai cách.

private string ExcelConnection(string fileName) 
    { 
     return 
      @"Provider=Microsoft.Jet.OLEDB.4.0;" + 
      @"Data Source=" + fileName + ";" + 
      @"Extended Properties=" + Convert.ToChar(34).ToString() + 
      @"Excel 8.0" + Convert.ToChar(34).ToString() + ";"; 
    } 

    private DataTable readExcel(string fileName, string sql) 
    { 
     OleDbConnection conn = new OleDbConnection(ExcelConnection(fileName)); 
     OleDbCommand cmd = new OleDbCommand(sql, conn); 
     OleDbDataAdapter adp = new OleDbDataAdapter(); 
     adp.SelectCommand = cmd; 
     DataTable dt = new DataTable(); 

     try 
     { 
      adp.FillSchema(dt, SchemaType.Source); 
      adp.Fill(dt); 
     } 
     catch 
     { 

     } 
     return dt; 
    } 
1

Sau khi tôi nghiên cứu lặp đi lặp lại, cuối cùng tôi đã tìm thấy 2 điều.
1.Sử dụng OLEDB, Nó không thể đọc tệp excel được bảo vệ bằng mật khẩu.
2. Mặc dù Interop có thể đọc tệp excel bất kể mật khẩu có được bảo vệ hay không, hiệu suất của nó không tốt bằng OLEDB.

Vì vậy, tôi có thể tạo mã dưới đây bằng cách kết hợp
1. OLEDB trong đó có hiệu suất rất tốt đẹp và
2. Interop mà có thể đọc tất cả các file excel.

public DataTable ReadPasswordProtectedExcel(string ExcelFilePath, string Password) 
{ 
    String TempExcelFilePath = string.Empty;    
    DataTable _DataTable = new DataTable(); 

    #region Get ExcelFile and Remove Password 
    { 
     String TempExcelFileName = string.Empty; 
     String DirectoryPath = string.Empty; 
     Microsoft.Office.Interop.Excel.Application excelapp = new Microsoft.Office.Interop.Excel.Application(); 
     excelapp.Visible = false; 

     Microsoft.Office.Interop.Excel.Workbook newWorkbook = excelapp.Workbooks.Open(ExcelFilePath, 0, 
              true, 5, Password, "", false, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", true, 
              false, 0, true, false, false); 

     TempExcelFileName = string.Format("{0}_{1}", "__", Path.GetFileName(ExcelFilePath)); // __xxx.xlsx 
     TempExcelFilePath = String.Format("{0}/{1}", Path.GetDirectoryName(ExcelFilePath), TempExcelFileName); 

     /// Create new excel file and remove password. 
     newWorkbook.SaveAs(TempExcelFilePath, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, "", "", 
     false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, 
     Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 

     newWorkbook.Close(true, "", false); 

     excelapp.Quit(); 
     Marshal.ReleaseComObject(excelapp); 
    } 
    #endregion 

    #region Get data from excel file by using OLEDB 
    { 
     _DataTable = ReadExcelFileInOLEDB(TempExcelFilePath); 
     ///Delete excel file 
     File.Delete(TempExcelFilePath); 
    } 
    #endregion 

    return _DataTable; 
} 

public DataTable ReadExcelFileInOLEDB(string _ExcelFilePath) 
{ 
    string ConnectionString = string.Empty; 
    string SheetName = string.Empty;   
    DataTable _DataTable = null; 
    DataSet _DataSet = null; 

    try 
    { 
     ConnectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=YES;IMEX=0;'", _ExcelFilePath); 
     using (OleDbConnection _OleDbConnection = new OleDbConnection(ConnectionString)) 
     { 
      _OleDbConnection.Open(); 
      _DataTable = _OleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); 

      if (_DataTable == null) 
       return null; 

      SheetName = _DataTable.Rows[0]["TABLE_NAME"].ToString(); 
      ConnectionString = string.Format("SELECT * FROM [{0}]", SheetName); 

      using (OleDbCommand _OleDbCommand = new OleDbCommand(ConnectionString, _OleDbConnection)) 
      { 
       using (OleDbDataAdapter _OleDbDataAdapter = new OleDbDataAdapter()) 
       { 
        _OleDbDataAdapter.SelectCommand = _OleDbCommand; 

        _DataSet = new DataSet(); 
        _OleDbDataAdapter.Fill(_DataSet, "PrintInfo"); 
        return _DataSet.Tables["PrintInfo"]; 
       } 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
} 

Cuối cùng Nếu bạn muốn loại bỏ dòng sản phẩm nào trong khi lấy dữ liệu từ excel, xin vui lòng kiểm tra this link và mã dưới đây

SELECT * FROM NAMED_RANGE WHERE [YourColumnTitle] IS NOT NULL 
Các vấn đề liên quan