Чтение защищенного паролем файла Excel, используя OLEDB в C # - PullRequest
11 голосов
/ 31 августа 2009

В моем приложении 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. Чтобы прочитать защищенный паролем файл, я попытался добавить поле пароля в строке подключения, но не смог прочитать файл. Я хочу знать, есть ли способ прочитать защищенные паролем файлы Excel, используя OLEDB, если я заранее знаю его пароль.

Ответы [ 4 ]

5 голосов
/ 10 декабря 2012

Если вы используете запрос для чтения файла 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;
    }
5 голосов
/ 31 августа 2009

Вот различные способы подключения к файлу Excel , включая OLEDB. В соответствии с этим, вы не можете открыть защищенный паролем файл стандартными методами. Вы должны использовать обходной путь.

Если книга Excel защищена пароль, вы не можете открыть его для доступ к данным, даже путем предоставления правильный пароль при подключении строка. Если вы попытаетесь, вы получите следующее сообщение об ошибке: «Не удалось расшифровать файл.

Это решение , хотя не в C #, но вы можете легко адаптировать его для своих целей.

Если вы не ЗНАЕТЕ пароль самостоятельно, альтернативой является перезапись файла без пароля. Вы можете использовать этот удобный проект и добавить к нему следующую подпрограмму:

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

Полная информация здесь .

2 голосов
/ 07 октября 2009

Вы можете использовать Поток OoXmlCrypto для доступа к зашифрованным файлам 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();
}
1 голос
/ 15 ноября 2013

После того, как я снова и снова исследовал, наконец, я нашел 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, проверьте эту ссылку и ниже код

SELECT * FROM NAMED_RANGE WHERE [YourColumnTitle] IS NOT NULL 
...