2009-08-31 11 views
11

W mojej aplikacji C# używam ciąg połączenia OLEDB "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\test.xls;Extended Properties=\"Excel 8.0;HDR=NO;ReadOnly=true;IMEX=1\"" do odczytu plików Excel. Aby odczytać plik chroniony hasłem, próbowałem dodać pole hasła w ciągu połączenia, ale nie mogłem odczytać pliku. Chcę wiedzieć, czy istnieje sposób, aby odczytać pliki Excel chronione hasłem za pomocą OLEDB, jeśli znam jego hasło wcześniej.Przeczytaj plik programu Excel chroniony hasłem za pomocą OLEDB w C#

+2

PWD = hasło próbowałeś? – Havenard

Odpowiedz

5

Oto different ways to connect to an Excel file, w tym OLEDB. Zgodnie z tym nie można otworzyć pliku chronionego hasłem standardowymi metodami. Musisz użyć obejścia.

Jeśli skoroszyt programu Excel jest chroniony hasło, nie można go otworzyć za dostępu do danych, nawet poprzez dostarczanie poprawne hasło z ciągu połączenia . Jeśli spróbujesz, otrzymasz następujący komunikat o błędzie: „Nie udało się plik odszyfrować

This is the solution, aczkolwiek nie w C#, ale można łatwo dostosować go do swoich celów

jeśli don”.. t znać hasło siebie, alternatywą jest ponowne zapisanie pliku bez hasła można używać this handy project i dodaj następującą procedurę do niego:..

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

Możesz użyć OoXmlCrypto stream, aby uzyskać dostęp do zaszyfrowanych plików Office 2007. Open source, zawiera zmodyfikowany pakiet ExcelPackage.

Przykładowy kod:

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

Jeśli używasz zapytanie do odczytu pliku Excel, to nie ma znaczenia, jeśli niektóre arkusze są chronione: To działa w obie strony.

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

Po tym, jak badałem raz po raz, w końcu znalazłem 2 rzeczy.
1. Korzystając z OLEDB, nie można odczytać pliku Excela, który jest chroniony hasłem.
2. Nawet jeśli Interop może czytać pliki excel niezależnie od tego, czy chronione hasłem, czy nie, jego wydajność nie jest tak dobra, jak OLEDB.

Więc tworzę poniżej kod łącząc
1. OLEDB który ma bardzo ładne osiągi i
2. Interop który może czytać każdy excel plików.

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; 
    } 
} 

Wreszcie Jeśli chcesz usunąć pusty wiersz podczas pobierania danych z programu Excel, należy sprawdzić this link i poniżej kodu

SELECT * FROM NAMED_RANGE WHERE [YourColumnTitle] IS NOT NULL 
Powiązane problemy