2009-08-31 42 views
11

En mi aplicación C# estoy usando la cadena de conexión OLEDB "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\test.xls;Extended Properties=\"Excel 8.0;HDR=NO;ReadOnly=true;IMEX=1\"" para leer archivos de Excel. Para leer un archivo protegido con contraseña intenté agregar un campo de contraseña en la cadena de conexión, pero no pude leer el archivo. Quiero saber si hay alguna forma de leer archivos Excel protegidos con contraseña usando OLEDB si conozco su contraseña de antemano.Lea el archivo de Excel protegido con contraseña usando OLEDB en C#

+2

PWD = contraseña ha intentado? – Havenard

Respuesta

5

Aquí están different ways to connect to an Excel file, incluyendo OLEDB. De acuerdo con esto, no puede abrir un archivo protegido con contraseña con métodos estándar. Tienes que usar una solución alternativa.

Si el libro de Excel está protegido por una contraseña , no se puede abrir para acceso a los datos, incluso mediante el suministro de la contraseña correcta con su cadena de conexión . Si lo intenta, recibirá el mensaje de error siguiente: "No se pudo archivo descifrar

This is the solution, aunque no en C#, pero fácilmente se podría adaptar para sus propósitos

Si no'.. t conocer la contraseña a sí mismo, una alternativa es volver a escribir el archivo sin una contraseña puede utilizar this handy project y añadir la siguiente rutina a la misma:..

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

Puede usar OoXmlCrypto stream para tener acceso a los archivos cifrados de Office 2007. Código abierto, incluye ExcelPackage modificado.

Código de ejemplo:

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

Si se utiliza una consulta para leer el archivo de Excel, no importa si algunas de las hojas están protegidos: Funciona en ambos sentidos.

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

Después de haber investigado una y otra vez, finalmente encontré 2 cosas.
1.Utilizando OLEDB, no se puede leer el archivo de Excel que está protegido por contraseña.
2. Aunque Interop puede leer archivos de Excel sin importar si están protegidos con contraseña o no, su rendimiento no es tan bueno como OLEDB.

Por lo tanto, crear código a continuación mediante la combinación de
1. OLEDB que tiene muy buen rendimiento y
2. interoperabilidad que pueden leer todos los archivos de 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; 
    } 
} 

Finalmente Si desea eliminar fila vacía al recuperar datos de Excel, por favor verifica this link y por debajo de código

SELECT * FROM NAMED_RANGE WHERE [YourColumnTitle] IS NOT NULL 
Cuestiones relacionadas