Рейтинг:
18
Maciej Los
Если вы хотите получить имя листа, вы должны использовать GetSchema
метод:
string sFileName = @"filename";
string sConStr = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR=YES';", sFileName);
DataTable dt = new DataTable();
using (OleDbConnection connection = new OleDbConnection(sConStr))
{
connection.Open();
var sheets = connection.GetSchema("TABLES").AsEnumerable()
.Select(x=>x.Field<string>("TABLE_NAME"))
.ToList();
foreach(var sheet in sheets) //loop through the collection of sheets ;)
{
//your logic here...
string myexceldataquery = string.Format("Select * FROM [{0}$]; ", sheet);
//get data
using(OleDbCommand oledbcmd = new OleDbCommand(myexceldataquery, oledbconn)
{
oledbconn.Open();
using(OleDbDataReader dr = oledbcmd.ExecuteReader())
{
//sql bulk copy here!
}
}
}
}
Удачи вам!
Member 14183767
привет , означает ли это, что мне больше не нужна эта строка кода : string myexceldataquery = "Select * FROM [$] ";?
Maciej Los
Нет. Вы должны пройти по кругу через коллекцию листов. Разница в том, что вы уже знаете название листа ;)
Member 14183767
я запутался Мацей, цикл проверяет наличие листа, а затем sqlbulkcopy скопирует все данные с листа в цикле. то есть мне больше не нужно указывать строку myexceldataquery?
Maciej Los
Проверьте обновленный ответ. Я надеюсь, что изменения, которые я внес в код, будут более понятны вам.
Удачи вам!
Member 14183767
Эй, Мацей, спасибо за изменения , я реализовал код вместе с блоком try catch, который он не вставляет, и я даже не получаю ошибку
Maciej Los
И вы думаете, что я могу догадаться, почему это произошло?
Вы должны отладить код и проверить причину странного поведения.
Member 14183767
хорошо спасибо
Member 14183767
Привет , как я могу исправить 'OleDb SqlException: компонент Microsoft Access database engine не может открыть или записать файл Excel. Он уже открыт исключительно другим пользователем, или вам нужно разрешение на просмотр и запись его данных.'
Maciej Los
Запустите Диспетчер задач и закройте все экземпляры MS Excel.
Member 14183767
привет Марсий , мне удалось собрать код вместе , и он работает, проблема в том, что он вставляет записи из листов excel несколько раз, вызывая дублирование записей в моей таблице, как я могу это предотвратить ? как в DataTable? вот фрагмент ниже: string ssqltable = "[dbo].[Апрель]";
пробовать{
string sConStr = строка.Формат("Поставщик=Майкрософт.Туз.Oledb для.12.0;Источник данных={0};расширенные свойства='программы Excel 8.0;HDR съемка=да';", sFileName);
DataTable dt = новый DataTable();
SqlConnection sqlconn = new SqlConnection(strConnString);
sqlconn.Открыть();
using (OleDbConnection connection = new OleDbConnection(sConStr))
{
соединение.Открыть();
dt = соединение.GetOleDbSchemaTable(OleDbSchemaGuid.Таблицы, новый объект[] { null, null, null, "таблица" });
var sheets = dt.Rows[0].Поле<string>("TABLE_NAME");
foreach(var sheet in sheets) //цикл через коллекцию листов ;)
{
//ваша логика здесь...
string myexceldataquery = строка.Формат("Select * FROM [{0}]; ", листы);
//получить данные
OleDbConnection oledbconn = новый OleDbConnection(sConStr);
OleDbCommand oledbcmd = new OleDbCommand(myexceldataquery, oledbconn);
оледбконн.Открыть();
И oledbdatareader др = oledbcmd.Метода executereader();
{
//sql bulk copy здесь!
DataTable table = new DataTable("benlist");
стол.Нагрузка(dr);
//установить путь
строка CurrentFilePath = Path.GetFullPath(fuAttachment.PostedFile.имя файла);
Session["filename"] = Path.GetFileNameWithoutExtension(CurrentFilePath);
SqlBulkCopy bulkcopy = новый SqlBulkCopy(strConnString);
переборка.DestinationTableName = ssqltable;
////Столбец таблицы сопоставления
переборка.ColumnMappings.Добавить("Идентификационный Номер", "[Идентификационный Номер]");
переборка.ColumnMappings.Добавить("дата рождения", "[Добролюбов]");
переборка.ColumnMappings.Add("BranchnameID", "[BranchnameID]");
переборка.ColumnMappings.Add("BranchCode", "[BranchCode]");
переборка.WriteToServer(таблица);
// }
соединение.Закрывать();
sqlconn.Закрывать();
}
}
}
}
catch (исключение){}
ClientScript.RegisterStartupScript(GetType(), "alert", "alert('File Uploaded');", true);
}
Maciej Los
Перед вставкой вы должны проверить, существует ли запись .
Я понятия не имею, как выглядит ваша база данных, и поэтому больше ничем не могу вам помочь.
Member 14183767
могу ли я не проверить datatable, чтобы увидеть, есть ли данные сначала, прежде чем они будут вставлены в базу данных ?
Рейтинг:
0
Vincent Maverick Durano
Я не делал этого раньше, но вы можете попробовать извлечь все имена листов excel, отфильтровать неизвестные имена и затем повторить итерацию к каждому из них перед вызовом bulkcopy.ColumnMappings.Add()
.
Например (непроверенный и урезанный для простоты):
//rest of your code goes here...
var sheetNames = GetExcelSheetNames("ThePathToYourExcelFileHere");
var unknownNames = sheetNames.Where(o => string.IsNullOrEmpty(o));
SqlBulkCopy bulkcopy = new SqlBulkCopy(strConnString);
bulkcopy.DestinationTableName = ssqltable;
//Mapping Table column
bulkcopy.ColumnMappings.Add("BeneficiaryID", "[BeneficiaryID]");
bulkcopy.ColumnMappings.Add("BeneficiaryName", "[BeneficiaryName]");
bulkcopy.ColumnMappings.Add("BranchNameID", "[BranchNameID]");
bulkcopy.ColumnMappings.Add("BranchCode", "[BranchCode]");
bulkcopy.ColumnMappings.Add("AccountType", "[AccountType]");
bulkcopy.ColumnMappings.Add("AccountNumber", "[AccountNumber]");
bulkcopy.ColumnMappings.Add("TotalWages", "[TotalWages]");
bulkcopy.ColumnMappings.Add("PaymentDate", "[PaymentDate]");
//set default names to unknown names
for(int i = 1; i <= unknownNames.Length; i++){
//map them to database
bulkcopy.ColumnMappings.Add("Unknown" + i.ToString(), "[Unknown" + i.ToString() + "]");
}
//rest of your code here
То
GetExcelSheetNames()
метод взят из этой статьи:
C# - Получение Имен Листов Книги Excel.[
^]
Member 14183767
что я помещаю в эту строку кода: string myexceldataquery = "Select * FROM [$] "; ?
Vincent Maverick Durano
Я думаю, что вам нужно использовать имя листа в вашем запросе Select. Возможно, это поможет: https://www.c-sharpcorner.com/article/import-excel-data-into-sql-table-using-sqlbulkcopy-in-c-sharp/