Загрузка листа Excel и импорт данных в базу данных SQL Server
Я разрабатываю это простое приложение для загрузки файла Excel (.xlsx
) и импортировать данные, присутствующие в этом листе Excel в базу данных SQL Server Express в .NET
я использую следующий код при нажатии кнопки импорта после просмотра и выбора файла для этого.
protected void Button1_Click(object sender, EventArgs e)
{
String strConnection = "Data Source=.SQLEXPRESS;AttachDbFilename='C:UsersHemantdocumentsvisual studio 2010ProjectsCRMdataCRMdataApp_DataDatabase1.mdf';Integrated Security=True;User Instance=True";
//file upload path
string path = FileUpload1.PostedFile.FileName;
//string path="C: Users HemantDocumentsexample.xlsx";
//Create connection string to Excel work book
string excelConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;Persist Security Info=False";
//Create Connection to Excel work book
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
//Create OleDbCommand to fetch data from Excel
OleDbCommand cmd = new OleDbCommand("Select [ID],[Name],[Designation] from [Sheet1$]", excelConnection);
excelConnection.Open();
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection);
//Give your Destination table name
sqlBulk.DestinationTableName = "Excel_table";
sqlBulk.WriteToServer(dReader);
excelConnection.Close();
}
но код не работает, когда я использую
string path = FileUpload1.PostedFile.FileName;`
и даже
string path="C: Users HemantDocumentsexample.xlsx";`
на dReader
не может принять путь в этом формат.
он может принимать путь только в следующем формате
string path="C: Users HemantDocumentsexample.xlsx";
то есть с в путь.Для чего мне нужно жестко закодировать путь, но мы должны просмотреть файл.
Итак, может ли кто-нибудь предложить решение использовать путь, пройденный FileUpload1
импортировать данные?
6 ответов
вы имеете дело с HttpPostedFile; это файл, который" загружен " на веб-сервер. Вам действительно нужно сохранить этот файл где-нибудь, а затем использовать его, потому что...
...в вашем случае просто так получилось, что вы размещаете свой веб-сайт на той же машине, где находится файл, поэтому путь доступен. Как только вы развернете свой сайт на другой машине, ваш код не будет работать.
разбейте это на два шага:
1) Сохраните файл где - нибудь-это очень распространено, чтобы увидеть это:
string saveFolder = @"C:\temp\uploads"; //Pick a folder on your machine to store the uploaded files
string filePath = Path.Combine(saveFolder, FileUpload1.FileName);
FileUpload1.SaveAs(filePath);
теперь у вас есть файл локально и реальная работа может быть сделано.
2) получить данные из файла. Ваш код должен работать как есть, но вы можете просто написать строку подключения следующим образом:
string excelConnString = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties="Excel 12.0";", filePath);
затем вы можете подумать об удалении файла, который вы только что загрузили и импортировали.
чтобы предоставить более конкретный пример, мы можем преобразовать ваш код в два методы:
private void SaveFileToDatabase(string filePath)
{
String strConnection = "Data Source=.\SQLEXPRESS;AttachDbFilename='C:\Users\Hemant\documents\visual studio 2010\Projects\CRMdata\CRMdata\App_Data\Database1.mdf';Integrated Security=True;User Instance=True";
String excelConnString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0\"", filePath);
//Create Connection to Excel work book
using (OleDbConnection excelConnection = new OleDbConnection(excelConnString))
{
//Create OleDbCommand to fetch data from Excel
using (OleDbCommand cmd = new OleDbCommand("Select [ID],[Name],[Designation] from [Sheet1$]", excelConnection))
{
excelConnection.Open();
using (OleDbDataReader dReader = cmd.ExecuteReader())
{
using(SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection))
{
//Give your Destination table name
sqlBulk.DestinationTableName = "Excel_table";
sqlBulk.WriteToServer(dReader);
}
}
}
}
}
private string GetLocalFilePath(string saveDirectory, FileUpload fileUploadControl)
{
string filePath = Path.Combine(saveDirectory, fileUploadControl.FileName);
fileUploadControl.SaveAs(filePath);
return filePath;
}
вы можете просто позвонить SaveFileToDatabase(GetLocalFilePath(@"C:\temp\uploads", FileUpload1));
вы можете рассмотреть другие Расширенные Свойства для строки подключения Excel. Они пригодятся!
другие улучшения, которые вы можете сделать, включают в себя ввод строки подключения к базе данных Sql в config и добавление правильной обработки исключений. Пожалуйста, рассмотрите этот пример только для демонстрации!
Не знаю, почему путь к файлу не работает, у меня есть подобный код, который работает нормально.
А если с двумя "\" это работает, вы всегда можете сделать path = path.Replace(@"\", @"\");
Попробуйте Использовать
string filename = путь.GetFileName (FileUploadControl.FileName);
сохраните файл в указанном месте, используя: FileUploadControl.PostedFile.SaveAs (strpath + filename);
вы можете использовать OpenXML SDK для *.xlsx файлы. Это работает очень быстро. Я сделал простую реализацию C# IDataReader для этого sdk. См.здесь. Теперь вы можете легко импортировать файл excel в базу данных sql server с помощью SqlBulkCopy. Он использует небольшую память, потому что он читает методом SAX (простой API для XML) (OpenXmlReader)
пример:
private static void DataReaderBulkCopySample()
{
using (var reader = new ExcelDataReader(@"test.xlsx"))
{
var cols = Enumerable.Range(0, reader.FieldCount).Select(i => reader.GetName(i)).ToArray();
DataHelper.CreateTableIfNotExists(ConnectionString, TableName, cols);
using (var bulkCopy = new SqlBulkCopy(ConnectionString))
{
// MSDN: When EnableStreaming is true, SqlBulkCopy reads from an IDataReader object using SequentialAccess,
// optimizing memory usage by using the IDataReader streaming capabilities
bulkCopy.EnableStreaming = true;
bulkCopy.DestinationTableName = TableName;
foreach (var col in cols)
bulkCopy.ColumnMappings.Add(col, col);
bulkCopy.WriteToServer(reader);
}
}
}
public async Task<HttpResponseMessage> PostFormDataAsync() //async is used for defining an asynchronous method
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var fileLocation = "";
string root = HttpContext.Current.Server.MapPath("~/App_Data");
MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(root); //Helps in HTML file uploads to write data to File Stream
try
{
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the file names.
foreach (MultipartFileData file in provider.FileData)
{
Trace.WriteLine(file.Headers.ContentDisposition.FileName); //Gets the file name
var filePath = file.Headers.ContentDisposition.FileName.Substring(1, file.Headers.ContentDisposition.FileName.Length - 2); //File name without the path
File.Copy(file.LocalFileName, file.LocalFileName + filePath); //Save a copy for reading it
fileLocation = file.LocalFileName + filePath; //Complete file location
}
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, recordStatus);
return response;
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
public void ReadFromExcel()
{
try
{
DataTable sheet1 = new DataTable();
OleDbConnectionStringBuilder csbuilder = new OleDbConnectionStringBuilder();
csbuilder.Provider = "Microsoft.ACE.OLEDB.12.0";
csbuilder.DataSource = fileLocation;
csbuilder.Add("Extended Properties", "Excel 12.0 Xml;HDR=YES");
string selectSql = @"SELECT * FROM [Sheet1$]";
using (OleDbConnection connection = new OleDbConnection(csbuilder.ConnectionString))
using (OleDbDataAdapter adapter = new OleDbDataAdapter(selectSql, connection))
{
connection.Open();
adapter.Fill(sheet1);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
A proposed solution will be:
protected void Button1_Click(object sender, EventArgs e)
{
try
{
CreateXMLFile();
SqlConnection con = new SqlConnection(constring);
con.Open();
SqlCommand cmd = new SqlCommand("bulk_in", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@account_det", sw_XmlString.ToString ());
int i= cmd.ExecuteNonQuery();
if(i>0)
{
Label1.Text = "File Upload successfully";
}
else
{
Label1.Text = "File Upload unsuccessfully";
return;
}
con.Close();
}
catch(SqlException ex)
{
Label1.Text = ex.Message.ToString();
}
}
public void CreateXMLFile()
{
try
{
M_Filepath = System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName);
fileExtn = Path.GetExtension(M_Filepath);
strGuid = System.Guid.NewGuid().ToString();
fNameArray = M_Filepath.Split('.');
fName = fNameArray[0];
xlRptName = fName + "_" + strGuid + "_" + DateTime.Now.ToShortDateString ().Replace ('/','-');
fileName = xlRptName.Trim() + fileExtn.Trim() ;
FileUpload1.PostedFile.SaveAs(ConfigurationManager.AppSettings["ImportFilePath"]+ fileName);
strFileName = Path.GetFileName(FileUpload1.PostedFile.FileName).ToUpper() ;
if (((strFileName) != "DEMO.XLS") && ((strFileName) != "DEMO.XLSX"))
{
Label1.Text = "Excel File Must be DEMO.XLS or DEMO.XLSX";
}
FileUpload1.PostedFile.SaveAs(System.Configuration.ConfigurationManager.AppSettings["ImportFilePath"] + fileName);
lstrFilePath = System.Configuration.ConfigurationManager.AppSettings["ImportFilePath"] + fileName;
if (strFileName == "DEMO.XLS")
{
strConn = "Provider=Microsoft.JET.OLEDB.4.0;" + "Data Source=" + lstrFilePath + ";" + "Extended Properties='Excel 8.0;HDR=YES;'";
}
if (strFileName == "DEMO.XLSX")
{
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + lstrFilePath + ";" + "Extended Properties='Excel 12.0;HDR=YES;'";
}
strSQL = " Select [Name],[Mobile_num],[Account_number],[Amount],[date_a2] FROM [Sheet1$]";
OleDbDataAdapter mydata = new OleDbDataAdapter(strSQL, strConn);
mydata.TableMappings.Add("Table", "arul");
mydata.Fill(dsExcl);
dsExcl.DataSetName = "DocumentElement";
intRowCnt = dsExcl.Tables[0].Rows.Count;
intColCnt = dsExcl.Tables[0].Rows.Count;
if(intRowCnt <1)
{
Label1.Text = "No records in Excel File";
return;
}
if (dsExcl==null)
{
}
else
if(dsExcl.Tables[0].Rows.Count >= 1000 )
{
Label1.Text = "Excel data must be in less than 1000 ";
}
for (intCtr = 0; intCtr <= dsExcl.Tables[0].Rows.Count - 1; intCtr++)
{
if (Convert.IsDBNull(dsExcl.Tables[0].Rows[intCtr]["Name"]))
{
strValid = "";
}
else
{
strValid = dsExcl.Tables[0].Rows[intCtr]["Name"].ToString();
}
if (strValid == "")
{
Label1.Text = "Name should not be empty";
return;
}
else
{
strValid = "";
}
if (Convert.IsDBNull(dsExcl.Tables[0].Rows[intCtr]["Mobile_num"]))
{
strValid = "";
}
else
{
strValid = dsExcl.Tables[0].Rows[intCtr]["Mobile_num"].ToString();
}
if (strValid == "")
{
Label1.Text = "Mobile_num should not be empty";
}
else
{
strValid = "";
}
if (Convert.IsDBNull(dsExcl.Tables[0].Rows[intCtr]["Account_number"]))
{
strValid = "";
}
else
{
strValid = dsExcl.Tables[0].Rows[intCtr]["Account_number"].ToString();
}
if (strValid == "")
{
Label1.Text = "Account_number should not be empty";
}
else
{
strValid = "";
}
if (Convert.IsDBNull(dsExcl.Tables[0].Rows[intCtr]["Amount"]))
{
strValid = "";
}
else
{
strValid = dsExcl.Tables[0].Rows[intCtr]["Amount"].ToString();
}
if (strValid == "")
{
Label1.Text = "Amount should not be empty";
}
else
{
strValid = "";
}
if (Convert.IsDBNull(dsExcl.Tables[0].Rows[intCtr]["date_a2"]))
{
strValid = "";
}
else
{
strValid = dsExcl.Tables[0].Rows[intCtr]["date_a2"].ToString();
}
if (strValid == "")
{
Label1.Text = "date_a2 should not be empty";
}
else
{
strValid = "";
}
}
}
catch
{
}
try
{
if(dsExcl.Tables[0].Rows.Count >0)
{
dr = dsExcl.Tables[0].Rows[0];
}
dsExcl.Tables[0].TableName = "arul";
dsExcl.WriteXml(sw_XmlString, XmlWriteMode.IgnoreSchema);
}
catch
{
}
}`enter code here`