Как импортировать Excel, который находится в формате HTML

Я экспортировал данные из базы данных с помощью HttpContext с форматированием таблицы, tr и td. Я хочу прочитать тот же файл и преобразовать в datatable.

<add name="Excel03ConString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='HTML Import;HDR={1};IMEX=1'" />

<add name="Excel03ConString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR={1};IMEX=1'" />

    private DataTable GetTableFromExcel()
    {
        DataTable dt = new DataTable();

        try
        {
            if (exclFileUpload.HasFile)
            {
                string FileName = Path.GetFileName(exclFileUpload.PostedFile.FileName);
                string Extension = Path.GetExtension(exclFileUpload.PostedFile.FileName);
                string FolderPath = Server.MapPath(ConfigurationManager.AppSettings["FolderPath"]);
                //string NewFileName = string.Format("{0}_{1}", DateTime.Now.ToString().Replace("/", "").Replace(" ", "").Replace(":", ""), FileName);
                string FilePath = Path.Combine(string.Format("{0}/{1}", FolderPath, FileName));
                exclFileUpload.SaveAs(FilePath);
                string conStr = "";
                switch (Extension)
                {
                    case ".xls": //Excel 97-03
                        conStr = ConfigurationManager.ConnectionStrings["Excel03ConString"].ConnectionString;
                        break;
                    case ".xlsx": //Excel 07
                        conStr = ConfigurationManager.ConnectionStrings["Excel07ConString"].ConnectionString;
                        break;
                }
                conStr = String.Format(conStr, FilePath, true);
                OleDbConnection connExcel = new OleDbConnection(conStr);
                OleDbCommand cmdExcel = new OleDbCommand();
                OleDbDataAdapter oda = new OleDbDataAdapter();

                cmdExcel.Connection = connExcel;

                connExcel.Open();
                DataTable dtExcelSchema;
                dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                string SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
                connExcel.Close();

                connExcel.Open();
                cmdExcel.CommandText = "SELECT * From [" + SheetName + "]";
                oda.SelectCommand = cmdExcel;
                oda.Fill(dt);
                connExcel.Close();
                File.Delete(FilePath);

            }
        }
        catch (Exception ex)
        {

        }
        return dt;
    }

При использовании второй строки подключения я получаю ошибку "Внешняя таблица не находится в ожидаемом формате при подключении. Open()." Но при первом использовании я получаю ошибку при чтении имени листа.

Скажите, пожалуйста, как читать лист или, прямо, данные из Excel.

Ответ 1

Я думаю, что эта сторонняя dll- (ExcellDataReader) может помочь решить вашу проблему.

FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);

//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
//...
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
//...
//4. DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();

//5. Data Reader methods
while (excelReader.Read())
{
    //excelReader.GetInt32(0);
}

//6. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();

Ответ 2

Я нашел это онлайн: Файл С# Excel OLEDB читает HTML IMPORT

Здесь они говорят:

Вместо использования имени листа вы должны использовать заголовок страницы в выберите оператор без $. SELECT * FROM [HTMLPageTitle]

В этом посте они также ссылаются на это руководство, которое может пригодиться, но слишком долго копировать здесь: http://ewbi.blogs.com/develops/2006/12/reading_html_ta.html

Если это не сработает, я думаю, вам придется воссоздать оригинал excel, чтобы он оставался файлом excel, а не HTML (если это вообще возможно в вашем сценарии)

Ответ 3

Вы можете столкнуться с этой проблемой по разным причинам. Существуют разные решения для этого, чтобы отладить решение от x86. Вот как вы можете изменить его на x86.

  • Щелкните правой кнопкой мыши на sloution из Visual studio.
  • Нажмите "Диспетчер конфигурации"
  • Выберите x86 из Active solution platform, если доступно
  • Если недоступно, нажмите New и выберите или введите x86 и нажмите "ОК".
  • Восстановите решение и запустите приложение.

Если это решение не решит вашу проблему, вам, возможно, придется установить 32 bit версию office system drivers. Вот полный article, объясняющий проблему.

Ответ 4

После глубоких исследований я нашел решение.

Сначала конвертируйте конкретный файл Excel на страницу html, используя следующий код.

File.Move(Server.MapPath("~/Foldername/ExcelName.xls",Path.ChangeExtension(Server.MapPath("~/Foldername/ExcelName.xls"), ".html"));

нам нужно загрузить HTML-строку и извлечь содержимое. тег содержит и теги, но может иметь свойства стиля. Поэтому сначала мы должны избегать этих свойств стиля и после того, как мы получим требуемый контент из таблицы.

string url = Server.MapPath("~/FolderName/Excelname.html");
WebClient wc = new WebClient();
string fileContent = wc.DownloadString(url);

Здесь мы должны отформатировать HTML-теги, чтобы избежать свойств стиля.

const string msgFormat = "table[{0}], tr[{1}], td[{2}], a: {3}, b: {4}";   
const string table_pattern = "<table.*?>(.*?)</table>"; 
const string tr_pattern = "<tr.*?>(.*?)</tr>"; 
const string td_pattern = "<td.*?>(.*?)</td>"; 
const string a_pattern = "<a href=\"(.*?)\"></a>"; 
const string b_pattern = "<b>(.*?)</b>";

После сквозного цикла мы можем найти элементы <tr> и <td>. Затем мы можем получить контент в тегах <td></td>, используя этот метод.

private static List<string> GetContents(string input, string pattern)
{ 
    MatchCollection matches = Regex.Matches(input, pattern, RegexOptions.Singleline); 
    List<string> contents = new List<string>(); 
    foreach (Match match in matches) 
    contents.Add(match.Value); 
    return contents; 
}

Затем мы можем вставить импортированные записи в базу данных по каждой строке.

Ссылка здесь