2009-08-31 247 views
11

在我的c#應用程序中,我使用OLEDB連接字符串「Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\test.xls;Extended Properties=\"Excel 8.0;HDR=NO;ReadOnly=true;IMEX=1\"」來讀取Excel文件。 爲了讀取受密碼保護的文件,我嘗試在連接字符串中添加密碼字段,但無法讀取文件。 我想知道有沒有辦法使用OLEDB讀取密碼保護的Excel文件,如果我事先知道密碼的話。使用C#中的OLEDB讀取密碼保護的excel文件

+2

PWD =密碼你試過嗎? – Havenard 2009-08-31 06:20:42

回答

5

這裏是different ways to connect to an Excel file,包括OLEDB。據此,您不能用標準方法打開受密碼保護的文件。您必須使用解決方法。

如果Excel工作簿是由 密碼保護的,你不能打開它 數據訪問,甚至用您的連接字符串 供應 正確的密碼。如果您嘗試,您會收到 以下錯誤信息:「無法 解密文件

This is the solution,儘管不是在C#中,但你可以輕鬆適應它爲您的目的

如果你不」。自己知道密碼,另一種是重新編寫的文件沒有密碼,您可以使用this handy project和下面的程序添加到它:。

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

您可以使用OoXmlCrypto stream訪問Office 2007加密文件。開放源代碼,包含修改後的ExcelPackage。

示例代碼:

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

如果您使用查詢來讀取Excel文件,它不會如一些板的保護重要:它仍然可以正常工作。

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

經過我反覆研究,終於找到了2件東西。
1.使用OLEDB,無法讀取密碼保護的excel文件。
2.即使Interop可以讀取excel文件,無論密碼保護與否,其性能都不如OLEDB。

所以,我結合
1 OLEDB它具有非常好的性能和
2.互操作可以讀取每一個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; 
    } 
} 

最後,如果你想在Excel中檢索數據刪除空行,請this link和下面的代碼

SELECT * FROM NAMED_RANGE WHERE [YourColumnTitle] IS NOT NULL