How to get names of all sheets in excel - dataset

I want to create a method to get names of all sheets in a workbook. My workbook has 7 sheets. If I want to read and save names of sheets to the variable excelSheets, I receive 9 names, where two names response to non-exists sheets ("lists$" and "TYPAB").
I don't understand where is the problem? How can I get names only the existing sheets?
public List<string> NamesOfSheets(string filename)
{
string con = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filename + ";Extended Properties='Excel 12.0;HDR=Yes;'";
using (OleDbConnection connection = new OleDbConnection(con))
{
connection.Open();
List<string> excelSheets;
try
{
DataTable dt = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
excelSheets = dt.Rows.Cast<DataRow>()
.Select(i => i["TABLE_NAME"].ToString()).ToList();
return excelSheets;
}
catch (Exception)
{
throw new Exception("Failed to get SheetName");
}
}
}

Oscar, thanks for your help, but office interlop doesn't solve my problem.
I found that "lists$" is hidden sheet, so only name TYPAB doesn't respond to any existing sheet.
So I added clause where and problem is solved. :)
public List<string> NamesOfSheets(string filename)
{
string con = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filename + ";Extended Properties='Excel 12.0;HDR=Yes;'";
List<string> excelSheets;
using (OleDbConnection connection = new OleDbConnection(con))
{
connection.Open();
try
{
DataTable dt = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
excelSheets = dt.Rows.Cast<DataRow>()
.Where(i => i["TABLE_NAME"].ToString().EndsWith("$") || i["TABLE_NAME"].ToString().EndsWith("$'"))
.Select(i => i["TABLE_NAME"].ToString()).ToList();
return excelSheets;
}
catch (Exception)
{
throw new Exception("Failed to get SheetName");
}
}
}

Why not use Office Interop for this?
foreach (Excel.Worksheet displayWorksheet in Globals.ThisWorkbook.Worksheets)
{
Debug.WriteLine(displayWorksheet.Name);
}
https://msdn.microsoft.com/en-us/library/59dhz064.aspx

Related

.NET Core 6 SQL Server connection without Entity Framework

I am new to .NET Core. I have defined the connection string in appsettings.json like this:
"ConnectionStrings": {
"TestBD": "Server=localhost;Database=Test;Trusted_Connection=True;MultipleActiveResultSets=true"
}
I am not using Entity Framework. I need to connect to the database using this connection string from the Program.cs file.
Any help is really appreciated. Thanks
You refer the following sample code to use ADO.NET in Asp.net 6 program.cs:
//required using Microsoft.Data.SqlClient;
app.MapGet("/movies", () =>
{
var movies = new List<Movie>();
//to get the connection string
var _config = app.Services.GetRequiredService<IConfiguration>();
var connectionstring = _config.GetConnectionString("DefaultConnection");
//build the sqlconnection and execute the sql command
using (SqlConnection conn = new SqlConnection(connectionstring))
{
conn.Open();
string commandtext = "select MovieId, Title, Genre from Movie";
SqlCommand cmd = new SqlCommand(commandtext, conn);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
var movie = new Movie()
{
MovieId = Convert.ToInt32(reader["MovieId"]),
Title = reader["Title"].ToString(),
Genre = reader["Genre"].ToString()
};
movies.Add(movie);
}
}
return movies;
});
The result like this:

Angular 11 HTTP POST to SQL Server Database

I am trying to post my inputs to my SQL Server database. I can in fact POST to the database, but I get back a blank response. I know it's because I am returning "Success" instead of my variables but how to I correctly format that for the return statement?
POST method:
[HttpPost]
public JsonResult Post(Weather Wea)
{
string query = #"INSERT INTO dbo.Information (Date, TemperatureC, TemperatureF, Summary) VALUES ('" + Wea.Date + #"'
,'" + Wea.TemperatureC + #"'
,'" + Wea.TemperatureF + #"'
,'" + Wea.Summary + #"'
)";
DataTable table = new DataTable();
string sqlDataSource = _configuration.GetConnectionString("WeatherAppCon");
SqlDataReader myReader;
using (SqlConnection myCon = new SqlConnection(sqlDataSource))
{
myCon.Open();
using (SqlCommand myCommand = new SqlCommand(query, myCon))
{
myReader = myCommand.ExecuteReader();
table.Load(myReader);
myReader.Close();
myCon.Close();
}
}
return new JsonResult("Success");
}
Front-end POST
export class PostDataComponent {
baseUrl: string;
date: number;
temperatureC: number;
summary: string;
weatherForm: FormGroup;
constructor(public http: HttpClient, #Inject('BASE_URL') baseUrl: string, private formBuilder: FormBuilder) {
this.baseUrl = "https://localhost:44347/WeatherForecast";
this.weatherForm = formBuilder.group({
Date: new FormControl(),
TemperatureC: new FormControl(),
Summary: new FormControl()
});
}
CreateData() {
const params = new HttpParams({
fromObject: {
'date': this.weatherForm.value.Date.toString(),
'temperatureC': this.weatherForm.value.TemperatureC.toString(),
'summary': this.weatherForm.value.Summary.toString()
}
});
console.log(params);
this.http.post(this.baseUrl, {},{ params: params }).subscribe(data => {
console.log(data);
});
}
}
Couple things here.
As marc_s commented, you should be using parameterization instead of concatenating to avoid any potential SQL injection:
string query = #"INSERT INTO dbo.Information (Date, TemperatureC, TemperatureF, Summary) VALUES (#Date, #TemperatureC, #TemperatureF, #Summary)";
...
using (System.Data.SqlClient.SqlCommand myCommand = new SqlCommand(query, myCon))
{
myCommand.Parameters.AddWithValue("#Date", Wea.Date);
myCommand.Parameters.AddWithValue("#TemperatureC", Wea.TemperatureC);
myCommand.Parameters.AddWithValue("#TemperatureF", Wea.TemperatureF);
myCommand.Parameters.AddWithValue("#Summary", Wea.Summary);
...
Unless you have a trigger on your target table with an output, your query isn't returning any data (just the number of rows inserted) and your SqlDataReader is empty. You could get rid of the reader/DataTable and use myCommand.ExecuteScalar() instead in this case. If you do have a trigger outputting the inserted data, disregard this.
If you don't have an output trigger but do still need to return the inserted values for whatever reason, you could keep your SqlDataReader and update your query to the following
string query = #"INSERT INTO dbo.Information (Date, TemperatureC, TemperatureF, Summary)
OUTPUT inserted.Date,inserted.TemperatureC,inserted.TemperatureF,inserted.Summary
VALUES (#Date, #TemperatureC, #TempreatureF, #Summary)";
Without knowing the response format you're looking for, it's hard to give an answer on how to generate it. If you need to return the inserted values, you could use the OUTPUT keyword as in the previous bullet and serialize your DataTable.

Trying to Export Datatable to Excel (1.000.000 Records) in Web API and Angular, Writing Streaming is throwing an Out of Memory Exception

Trying to Export Datatable to Excel (1.000.000 Records) in Web API and Angular, Writing Streaming is throwing an Out of Memory Exception.
Tried Splitting Datatables with 100.000 records each and writing stream seperately. However when I try to concat the stream, Out Of Memory Exception occurs.
Is it ever possible to export 1.000.000 records in an excel sheet. I am able to export upto 175.000 records. But require 1.000.000. See Snippet Below.
[HttpPost]
public HttpResponseMessage DownloadExcel([FromBody]AuditRequest auditRequest)
{
HttpResponseMessage result = Request.CreateResponse(HttpStatusCode.OK);
var response = GetAuditForDownload(auditRequest);
MemoryStream streamFinal = new MemoryStream();
List<AuditRequest> auditListForBulk = new List<AuditRequest>();
foreach (AuditRequest req in response.Data)
{
req.FromDate = auditRequest.FromDate;
req.ToDate = auditRequest.ToDate;
}
DataTable table = ConvertToDataTable(response.Data);
List<DataTable> splittedtables = table.AsEnumerable()
.Select((row, index) => new { row, index })
.GroupBy(x => x.index / 100000) //integer division, the fractional part is truncated
.Select(g => g.Select(x => x.row).CopyToDataTable())
.ToList();
splittedtables.ForEach(delegate (DataTable SplitTable)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(ToCSV(SplitTable).ToString());
writer.Flush();
stream.Position = 0;
stream.CopyTo(streamFinal);
//byteArray = GetBytesFromDataSet(SplitTable);
//byteArrayFinal = byteArrayFinal.Concat(byteArray).ToArray();
});
result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(streamFinal.ToArray()) };
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "File.csv"
};
return result;
}

Uploading to SQL Server database offline

I'm trying to achieve a method whereby when a user upload a PDF document to a SQL Server database. The data would be uploaded instantly if network is available, but if there is no internet connection - the data would be stored somewhere else and be uploaded when internet connection is back. Please any idea how to achieve this?
Here is my code for the upload:
//CheckIfNetworkConnected( ) ;
Ping p = new Ping();
try
{
string host = "www.google.com";
//bool result = false;
PingReply reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
{
// Display form modelessly
pleaseWait.Show();
// Allow main UI thread to properly display please wait form.
Application.DoEvents();
using (SqlConnection con = new SqlConnection("Server=tcp:mycompany.database.windows.net,1433;Initial Catalog=DBmycompany;Persist Security Info=False;User ID=abubakarkabiru;Password=wordpass123#;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30"))
{
FileStream fStream = File.OpenRead(filepath);
byte[] contents = new byte[fStream.Length];
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
con.Open();
cmd = new SqlCommand("Insert into document values(#Staffname, #unit, #sites, #docname, #dateofreciept, #descriptions, #doc, #category, #housetype)", con);
if (textBox1.Visible == true)
{
cmd.Parameters.AddWithValue("#Unit", textBox1.Text);
cmd.Parameters.AddWithValue("#Staffname", textBox2.Text);
}
else
{
cmd.Parameters.AddWithValue("#Staffname", comboDesigner.SelectedItem.ToString());
cmd.Parameters.AddWithValue("#unit", comboUnit.SelectedItem.ToString());
}
cmd.Parameters.AddWithValue("#category", comboCategory.SelectedItem.ToString());
if (string.IsNullOrWhiteSpace(txtdocname.Text))
{
errorProvider1.SetError(txtdocname, "Compulsory");
}
else
{
cmd.Parameters.AddWithValue("#docname", string.IsNullOrWhiteSpace(txtdocname.Text));
}
cmd.Parameters.AddWithValue("#dateofreciept", dateTimePicker1.Value.ToShortDateString());
cmd.Parameters.AddWithValue("#doc", contents);
cmd.Parameters.AddWithValue("#sites", string.IsNullOrWhiteSpace(comboSites.ToString())
? (Object)comboSites.SelectedItem.ToString()
: (Object)DBNull.Value);
cmd.Parameters.AddWithValue("#housetype", string.IsNullOrWhiteSpace(comboHouseType.ToString())
? (Object)comboHouseType.SelectedItem.ToString()
: (Object)DBNull.Value);
cmd.Parameters.AddWithValue("#descriptions", string.IsNullOrWhiteSpace(txtDesc.Text)
? (object)txtDesc.Text
: (object)DBNull.Value);
var i = cmd.ExecuteNonQuery();
if (i > 0)
{
MessageBox.Show("Successful");
this.notifyIcon1.Icon = this.Icon;
this.notifyIcon1.ShowBalloonTip(600, "Upload Notice", "New Document has been Uploaded", ToolTipIcon.Info);
//notifyUpload();
}
con.Close();
}
pleaseWait.Hide();
cleaBoxes();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

Facing trouble while inserting bulk data into sql

In MVC4 , i have following code in my view :
<script>
var things = [];
function fun () {
var Quran = {
"surah": things[1].surah,
"ayah": things[1].ayah,
"verse": things[1].verse
};
things.push(Quran);
for (var n = 0; n < length; n++) {
$.ajax({
contentType: 'application/json; charset=utf-8',
method: 'GET',
url: "Gateway/DB_Rola?action=1",
data: things[n],
success: function (Data) {
var mera_obj = Data.key;
document.getElementById("Param2").value = '(' + mera_obj.Response_Code + ' , ' + mera_obj.Response_Description + ')';
},
error: function () {
alert("ERROR: can't connect to Server this time");
return false; }
});
alert("done for "+(n+1));
} // loop ends
return false;
}; // function ends
and controller method is :
public ActionResult DB_Rola(thing things)
{
string connectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\PROGRAM FILES (X86)\MICROSOFT SQL SERVER\MSSQL.1\MSSQL\DATA\PEACE_QURAN.MDF;Integrated Security=True";
System.Data.SqlClient.SqlConnection connection = new SqlConnection(connectionString);
int surah = things.surah;
int ayah =things.ayah;
String verse = things.verse;
// designing parametiric_query from the parameters
string query = "insert into Ayyat_Translation_Language_old_20131209 values(null,null,#Surah,#Verse)";
SqlCommand cmd = new SqlCommand(query, connection);
connection.Open();
//setting parameters for parametric query
SqlParameter Parm1 = new SqlParameter("Surah", surah);
SqlParameter Parm2 = new SqlParameter("Ayah", ayah);
SqlParameter Parm3 = new SqlParameter("Verse", verse);
//adding parameters
cmd.Parameters.Add(Parm1);
cmd.Parameters.Add(Parm2);
cmd.Parameters.Add(Parm3);
cmd.ExecuteNonQuery();
System.IO.StreamWriter file = new System.IO.StreamWriter(#"E:\Office_Work\Peace_Quran\Peace_Quran\Files\hisaab.txt", true);
file.WriteLine(" "+things.ayah);
file.Close();
connection.Close();
return View();
}
as mentioned above in code ,there is loop in my view page that passes single object at a time which is received in above controller method .it works for small amount of data but when i send bulk .i.e. 50+ records at once, some of records are not saved in my DB. i don't know what's wrong with my DB code. please help me figure it out.

Resources