How to use Using the HtmlAgilityPack to get table value - asp.net

http://www.dsebd.org/latest_PE_all2_08.php
i work on asp.net C# web.Above url contain some information ,i need to save them in my database and also need to save then in specified location as xml format.This url contain a table.I want to get this table value but how to retrieve value from this html table.
HtmlWeb htmlWeb = new HtmlWeb();
// Creates an HtmlDocument object from an URL
HtmlAgilityPack.HtmlDocument document = htmlWeb.Load("http://www.dsebd.org/latest_PE_all2_08.php");
I need help to get table information from this document .How to save this table value.Show me some syntax

public partial class WebForm3 : System.Web.UI.Page
{
private byte[] aRequestHTML;
private string myString = null;
protected System.Web.UI.WebControls.Label Label1;
private ArrayList a = new ArrayList();
protected void Page_Load(object sender, EventArgs e)
{
WebClient objWebClient = new WebClient();
aRequestHTML = objWebClient.DownloadData("http://www.dsebd.org/latest_PE_all2_08.php");
// creates UTf8 encoding object
UTF8Encoding utf8 = new UTF8Encoding();
// gets the UTF8 encoding of all the html we got in aRequestHTML
myString = utf8.GetString(aRequestHTML);
string html = #"
<html><head></head>
<body><div>
<table border=1>
<tr><td>sno</td><td>sname</td></tr>
<tr><td>111</td><td>abcde</td></tr>
<tr><td>213</td><td>ejkll</td></tr>
</table>
<table border=1>
<tr><td>adress</td><td>phoneno</td><td>note</td></tr>
<tr><td>asdlkj</td><td>121510</td><td>none</td></tr>
<tr><td>asdlkj</td><td>214545</td><td>none</td></tr>
</table>
</div></body>
</html>";
HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(myString);
DataTable addressAndPhones;
foreach (var table in ParseAllTables(htmlDoc))
{
if (table.Columns.Contains("Trading Code") && table.Columns.Contains("Close Price"))
{
// You found the address and phone number table
addressAndPhones = table;
}
}
}
private static DataTable[] ParseAllTables(HtmlDocument doc)
{
var result = new List<DataTable>();
foreach (var table in doc.DocumentNode.Descendants("table"))
{
result.Add(ParseTable(table));
}
return result.ToArray();
}
private static DataTable ParseTable(HtmlNode table)
{
var result = new DataTable();
var rows = table.Descendants("tr");
var header = rows.Take(1).First();
foreach (var column in header.Descendants("td"))
{
result.Columns.Add(new DataColumn(column.InnerText, typeof(string)));
}
foreach (var row in rows.Skip(1))
{
var data = new List<string>();
foreach (var column in row.Descendants("td"))
{
data.Add(column.InnerText);
}
result.Rows.Add(data.ToArray());
}
return result;
}
}
In this way u can easily create a DataTable and then can save is DataBase.

Related

mail merge with dynamic file path

I had a problem generating a word template because I wanted it to be selected dynamically with ddlTemplate when selected to write in it with the merge field in the word template.
this is my code:
public partial class unTemplate : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)// call the method for ONLY first time for visitor
{
{
populateDdlInstitution();
}
}
}
protected void populateDdlInstitution()
{
CRUD myCrud = new CRUD();
string mySql = #"select institutionid, institution from institution";
SqlDataReader dr = myCrud.getDrPassSql(mySql);
ddlInstitution.DataTextField = "institution";
ddlInstitution.DataValueField = "institutionid";
ddlInstitution.DataSource = dr;
ddlInstitution.DataBind();
}
protected void ddlInstitution_SelectedIndexChanged(object sender, EventArgs e)
{
// call a method to populate the template ddl
populateDdlTemplate();
}
protected void populateDdlTemplate()
{
CRUD myCrud = new CRUD();
string mySql = #"select internDocId, DocName
from internDoc
where institutionId = #institutionId";
Dictionary<string, object> myPara = new Dictionary<string, object>();
myPara.Add("#institutionId", ddlInstitution.SelectedItem.Value);
SqlDataReader dr = myCrud.getDrPassSql(mySql, myPara);
ddlTemplate.DataTextField = "DocName";
ddlTemplate.DataValueField = "internDocId";
ddlTemplate.DataSource = dr;
ddlTemplate.DataBind();
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
CRUD myCrud = new CRUD();
string mySql = #"select* from intern
where institutionId = #institutionId"/*+#"select internDocId,DocName from internDoc where internDocId=internDocId"*/;
Dictionary<string, object> myPara = new Dictionary<string, object>();
myPara.Add("#institutionId", ddlInstitution.SelectedItem.Value);
//myPara.AsEnumerable(#"internDocId");
SqlDataReader dr = myCrud.getDrPassSql(mySql, myPara);
gvData.DataSource = dr;
gvData.DataBind();
}
protected void btnGenerateTemplate_Click(object sender, EventArgs e)
{
wordT();
}
private static DataTable GetRecipients()
{
//Creates new DataTable instance.
DataTable table = new DataTable();
//Loads the database.
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + #"../../CustomerDetails.mdb");
//Opens the database connection.
conn.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter("Select * from intern", conn);
//Gets the data from the database.
adapter.Fill(table);
//Releases the memory occupied by database connection.
adapter.Dispose();
conn.Close();
return table;
}
public void wordT()
{
for (int i = 0; i <= gvData.Rows.Count - 1; i++)
{
String internId = gvData.Rows[i].Cells[0].Text;
String fullName = gvData.Rows[i].Cells[7].Text;
String cell = gvData.Rows[i].Cells[8].Text;
String email = gvData.Rows[i].Cells[9].Text;
Syncfusion.DocIO.DLS.WordDocument document = new Syncfusion.DocIO.DLS.WordDocument(Server.MapPath(getPath()));
//Deleting null fields
document.MailMerge.RemoveEmptyParagraphs = true;
string[] fieldNames = new string[] { "fullName", "internId", "email", "cell" };
string[] fieldValues = new string[] { fullName, internId, email, cell };
// mail merge
document.MailMerge.Execute(fieldNames, fieldValues);
//Saves
document.Save(Server.MapPath("~/myDoc/" + email + ".docx"));
document.Close();
}
// pass message to user notifying of successfull operation
lblOutput.Text = "Word Doc output generated successfully!";
}
public string getPath()
{
DirectoryInfo di = new DirectoryInfo(#"C:\projects\unSupervisorApp\Uploads\");
foreach (var d in di.EnumerateDirectories())
{
foreach (var fi in d.EnumerateFileSystemInfos())
{
if (fi.Name == (ddlTemplate.DataTextField))
{
return fi.FullName.Replace(fi.Name, "");
}
}
}
return di.FullName;
}
}//cls
the problem:
‎1-'C:/projects/unSupervisorApp/Uploads/' is a physical path but was expected to be a virtual path.‎
2- and sometime it gives me that it i can not find the file in EnumerateDirectories.
but i get the first one the most.
getFile
getPath
path of folder + ddlselectedItem.text

How do I change the format of a specific column in EPPlus?

I've used EPPlus to download my datatable from my website / database to an Excel sheet and the first picture is the result I get. The second picture is what I would like it to be.
Questions:
How do I change the format of my Timestamp to "time"?
Obviously title would still be a string format.
How do I make the width of the columns to match the longest word inside?
So that 80% of the message isn't hidden and you have to drag the column out to read the entire message.
Edit: Completely forgot to add my code...
public ActionResult ExportData()
{
DataTable dataTable = GetData();
using (ExcelPackage package = new ExcelPackage())
{
var ws = package.Workbook.Worksheets.Add("My Sheet");
//true generates headers
ws.Cells["1:1"].Style.Font.Bold = true;
ws.Cells["A1"].LoadFromDataTable(dataTable, true);
ws.Cells[ws.Dimension.Address].AutoFitColumns();
var stream = new MemoryStream();
package.SaveAs(stream);
string fileName = "Log.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
stream.Position = 0;
return File(stream, contentType, fileName);
}
}
public DataTable GetData()
{
DataTable dt = new DataTable();
if (ModelState.IsValid)
{
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MySqlConnection"].ConnectionString))
{
using (SqlCommand comm = conn.CreateCommand())
{
comm.Parameters.AddWithValue("#val1", Session["myID"]);
comm.Parameters.AddWithValue("#val2", "%" + Session["mySearchString"] + "%");
comm.CommandText = "SELECT * FROM dbo.Log WHERE CustomerId = #val1 AND Message LIKE #val2";
try
{
conn.Open();
dt.Load(comm.ExecuteReader());
}
catch (SqlException e)
{
throw new Exception(e.ToString());
}
}
}
}
return dt;
}
Just need to set the Numberformat.Format string. Like this:
ws.Column(2).Style.Numberformat.Format = "hh:mm:ss";
If you want to customize the actual just there are plenty of resource online like http://www.ozgrid.com/Excel/excel-custom-number-formats.htm. Or you can just open it in excel, set the format to Custom and experiment with the string.

Export data to SQL Server 2005 from CSV file

Following asp.net code fetches data from CSV file and inserts it into SQL server 2005 table.
However, i need to specify Table name, Field names whose data will be fetched, plus mapping info(Mapping between 'column names of CSV' and 'column names of table') statically in code.
How can i modify below code so that it works for any Table name.
In short, Table name and Mapping should be handled dynamically.
public class CsvBulkCopyDataIntoSqlServer
{
protected const string _truncateLiveTableCommandText = #"TRUNCATE TABLE Account";
protected const int _batchSize = 100000;
static void Main(string[] args)
{
LoadCsvDataIntoSqlServer();
}
public static void LoadCsvDataIntoSqlServer()
{
// This should be the full path
var fileName = #"D:\output.csv";
var createdCount = 0;
using (var textFieldParser = new TextFieldParser(fileName))
{
textFieldParser.TextFieldType = FieldType.Delimited;
textFieldParser.Delimiters = new[] { "," };
textFieldParser.HasFieldsEnclosedInQuotes = true;
// var connectionString = ConfigurationManager.ConnectionStrings["CMSConnectionString"].ConnectionString;
string connectionString = "Data Source= 172.25.10.4" + ";Initial Catalog= SFdata" + ";Persist Security Info=True;User ID= sa" + ";Password= Newuser#123";
var dataTable = new DataTable("Account");
// Add the columns in the temp table
dataTable.Columns.Add("Name");
dataTable.Columns.Add("shippingstreet");
dataTable.Columns.Add("shippingpostalcode");
dataTable.Columns.Add("ShippingCountry");
dataTable.Columns.Add("shippingstate");
//dataTable.Columns.Add("LastName");
using (var sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
// Truncate the live table
using (var sqlCommand = new SqlCommand(_truncateLiveTableCommandText, sqlConnection))
{
sqlCommand.ExecuteNonQuery();
}
// Create the bulk copy object
var sqlBulkCopy = new SqlBulkCopy(sqlConnection)
{
DestinationTableName = "Account"
};
// Setup the column mappings, anything ommitted is skipped
sqlBulkCopy.ColumnMappings.Add("Name", "Name");
sqlBulkCopy.ColumnMappings.Add("shippingstreet", "shippingstreet");
sqlBulkCopy.ColumnMappings.Add("shippingpostalcode", "shippingpostalcode");
sqlBulkCopy.ColumnMappings.Add("ShippingCountry", "ShippingCountry");
sqlBulkCopy.ColumnMappings.Add("shippingstate", "shippingstate");
// Loop through the CSV and load each set of 100,000 records into a DataTable
// Then send it to the LiveTable
while (!textFieldParser.EndOfData)
{
dataTable.Rows.Add(textFieldParser.ReadFields());
createdCount++;
if (createdCount % _batchSize == 0)
{
InsertDataTable(sqlBulkCopy, sqlConnection, dataTable);
break;
}
}
InsertDataTable(sqlBulkCopy, sqlConnection, dataTable);
sqlConnection.Close();
}
}
}
protected static void InsertDataTable(SqlBulkCopy sqlBulkCopy, SqlConnection sqlConnection, DataTable dataTable)
{
sqlBulkCopy.WriteToServer(dataTable);
dataTable.Rows.Clear();
}
}
Why don't you use SQL Server Integration Services, it will make your life easier

Pdf's fields should remain editable using itextsharp in asp.net

I have a fillable pdf. In which i have few textboxes.
I fill these fields by using following code(itextsharp).
DataTable dt = new DataTable();
String pdfPath1 = Server.MapPath("pdfs\\transmittal2.pdf");
if (File.Exists(pdfPath1))
{
dt = objClsTransmittal.GetTransmittal(jobid, cid);
String comment = "Correspondence generated for " + dt.Rows[0]["Recipient"].ToString();
var formfield = PDFHelper.GetFormFieldNames(pdfPath1);
formfield["DocDate"] = DateTime.Now.ToLongDateString();
formfield["Address1"] = dt.Rows[0]["Company"].ToString();
formfield["Address2"] = dt.Rows[0]["Address1"].ToString();
formfield["PropertyAddress"] = dt.Rows[0]["PropertyAddress"].ToString();
formfield["Job"] = dt.Rows[0]["JobID"].ToString();
formfield["Name"] = dt.Rows[0]["Recipient"].ToString();
formfield["CityStateZip"] = dt.Rows[0]["address2"].ToString();
formfield["E-mail"] = dt.Rows[0]["Email"].ToString();
var pdfcontent = PDFHelper.GeneratePDF(pdfPath1, formfield);
PDFHelper.ReturnPDF(pdfcontent, "Transmittal.pdf");
}
Currently its downloded as read only pdf.
when this pdf gets downloaded, i want that all fields still remain fillable, with the text i have filled in pdf. So that i can edit the text.
I'm looking forward for your replies.
Thanks.
EDIT
PdfHelper is my custom class. In which i have used following code:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.IO;
using iTextSharp.text.pdf;
public class PDFHelper
{
public static Dictionary<string, string> GetFormFieldNames(string pdfPath)
{
var fields = new Dictionary<string, string>();
var reader = new PdfReader(pdfPath);
foreach (DictionaryEntry entry in reader.AcroFields.Fields)
fields.Add(entry.Key.ToString(), string.Empty);
reader.Close();
return fields;
}
public static byte[] GeneratePDF(string pdfPath, Dictionary<string, string> formFieldMap)
{
var output = new MemoryStream();
var reader = new PdfReader(pdfPath);
var stamper = new PdfStamper(reader, output);
var formFields = stamper.AcroFields;
foreach (var fieldName in formFieldMap.Keys)
formFields.SetField(fieldName, formFieldMap[fieldName]);
stamper.FormFlattening = true;
stamper.Close();
reader.Close();
return output.ToArray();
}
public static string GetExportValue(AcroFields.Item item)
{
var valueDict = item.GetValue(0);
var appearanceDict = valueDict.GetAsDict(PdfName.AP);
if (appearanceDict != null)
{
var normalAppearances = appearanceDict.GetAsDict(PdfName.N);
if (normalAppearances != null)
{
foreach (var curKey in normalAppearances.Keys)
if (!PdfName.OFF.Equals(curKey))
return curKey.ToString().Substring(1); // string will have a leading '/' character, so remove it!
}
}
var curVal = valueDict.GetAsName(PdfName.AS);
if (curVal != null)
return curVal.ToString().Substring(1);
else
return string.Empty;
}
public static void ReturnPDF(byte[] contents)
{
ReturnPDF(contents, null);
}
public static void ReturnPDF(byte[] contents, string attachmentFilename)
{
var response = HttpContext.Current.Response;
if (!string.IsNullOrEmpty(attachmentFilename))
response.AddHeader("Content-Disposition", "attachment; filename=" + attachmentFilename);
response.ContentType = "application/pdf";
response.BinaryWrite(contents);
response.End();
}
Your code line
stamper.FormFlattening = true;
instructs iTextSharp to flatten the form fields, i.e. to integrate them into the page content and remove the form field annotations.
As you want to keep the form fields as editable fields, don't flatten the form.
Error: Cannot convert type in PDFHelper.cs
public static Dictionary<string, string> GetFormFieldNames(string pdfPath)
{
var fields = new Dictionary<string, string>();
var reader = new PdfReader(pdfPath);
foreach (DictionaryEntry entry in reader.AcroFields.Fields) //ERROR: 'System.Collections.Generic.KeyValuePair' to 'System.Collections.DictionaryEntry'
{
fields.Add(entry.Key.ToString(), string.Empty);
}
reader.Close();
return fields;
}
'System.Collections.Generic.KeyValuePair' to 'System.Collections.DictionaryEntry'

ASP.NET: Shortest way to render DataTable to a string (HTML)?

What is the shortest way to convert a DataTable into a string (formatted in HTML)?
Programmatically binding to a UI control and rendering to an ASP.NET page is not acceptable. Can't depend on the ASP.NET page lifecycle.
The purpose of this shouldn't matter, but to satisfy curiosity: This is for logging/debugging/dump purposes in algorithms that do a lot of DataTable processing.
Thanks!
You can use the ASP.net controls such as GridView, DataGrid and point them render into StringBuilder using StringWriter, No need to use ASP.net page for this, this is a simple example in Console
class Program
{
static void Main(string[] args)
{
IList<Person> persons = new List<Person>()
{
new Person{Id = 1, Name="Test Name 1"},
new Person{Id = 2, Name="Test Name 2"}
};
GridView gridView = new GridView();
StringBuilder result = new StringBuilder();
StringWriter writer = new StringWriter(result);
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
gridView.DataSource = persons;
gridView.DataBind();
gridView.RenderControl(htmlWriter);
Console.WriteLine(result);
}
}
class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
I use this function through my application. It's pretty straightforward
static public string ConvertDataTableToHTMLString(System.Data.DataTable dt, string filter, string sort, string fontsize, string border, bool headers, bool useCaptionForHeaders)
{
StringBuilder sb = new StringBuilder();
sb.Append("<table border='" + border + "'b>");
if (headers)
{
//write column headings
sb.Append("<tr>");
foreach (System.Data.DataColumn dc in dt.Columns)
{
if (useCaptionForHeaders)
sb.Append("<td><b><font face=Arial size=2>" + dc.Caption + "</font></b></td>");
else
sb.Append("<td><b><font face=Arial size=2>" + dc.ColumnName + "</font></b></td>");
}
sb.Append("</tr>");
}
//write table data
foreach (System.Data.DataRow dr in dt.Select(filter,sort))
{
sb.Append("<tr>");
foreach (System.Data.DataColumn dc in dt.Columns)
{
sb.Append("<td><font face=Arial size=" + fontsize + ">" + dr[dc].ToString() + "</font></td>");
}
sb.Append("</tr>");
}
sb.Append("</table>");
return sb.ToString();
}
If this is just for purposes of logging, might it not make more sense to log them out as XML - easier to manipulate if you need to. You just need to call the WriteXml method.
Create the control, create an HTML Writer, set any settings or databind the control, then call the render method, using the HTML Writer.
You can then get the string out of the writer.
Edit: I initially misread the question and thought you wanted to render a datagrid.
A Datatable can easily be rendered to its XML.
you asked for HTML.
here is a console app code that will render a datatable using a datagrid control.
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Column1");
dt.Columns.Add("Column2");
dt.Rows.Add("RowValue1", "Field2RowValue1");
dt.Rows.Add("RowValue2", "Field2RowValue2");
DataGrid dg = new DataGrid();
dg.DataSource = dt;
dg.DataBind();
StringWriter sw = new StringWriter();
HtmlTextWriter w = new HtmlTextWriter(sw);
dg.RenderControl(w);
Console.Write(sw.ToString());
Console.ReadLine();
}
}

Resources