I'm generating a HTML file using C#. Using objects and their properties, I'm adding rows to an HTML table . However, I'm seeing some duplicate rows which I don't want, even though the column values are correct. After doing some googling, I found a few HTML functions that people posted for accomplishing this, such as:
function removeDuplicateRows($table){
function getVisibleRowText($row){
return $row.find('td:visible').text().toLowerCase();
}
$table.find('tr').each(function(index, row){
var $row = $(row);
$row.nextAll('tr').each(function(index, next){
var $next = $(next);
if(getVisibleRowText($next) == getVisibleRowText($row))
$next.remove();
})
});
}
and
var seen = {};
$('table tr').each(function() {
var txt = $(this).text();
if (seen[txt])
$(this).remove();
else
seen[txt] = true;
});
However, I'm not sure how to utilize those in my c# code (possibly from my lack of HTML coding). When I tried using these and wrap each line with a sw.WriteLine, all I get is text of the function. So my question is, how can I remove duplicate HTML table rows in my code?
What I have:
StreamWriter sw = new StreamWriter(Path.Combine(cdsPublishRoot, "GeneralActive.htm"));
sw.WriteLine("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \" http://www.w3.org/TR/html4/strict.dtd \">");
sw.WriteLine("<html>");
sw.WriteLine("<head>");
sw.WriteLine("<meta http-equiv=\"Expires\" content=\"0\">");
sw.WriteLine("<title>GPCSE-CDS General</title>");
sw.WriteLine("</head>");
sw.WriteLine("<body onmousemove=\"MouseMove(event)\">");
sw.WriteLine("<script type=\"text/javascript\">");
sw.WriteLine("DoMainMenu(false,\"SDS\");");
sw.WriteLine("DoSdsSubMenu(true,\"ARCHIVE\");");
sw.WriteLine("</script>");
sw.WriteLine("<p class=Heading2><br>Active PCM General Requirement Specifications<br></p>");
sw.WriteLine("<table cellpadding=5 cellspacing=0 border=1 width=760 id=\"MainDataTable\">");
sw.WriteLine("<tr><th style=\"width:14%\" align=left class=SdsHeader>Spec.</th>");
sw.WriteLine("<th style=\"width:64%\" align=left class=SdsHeader>Specification Name</th>");
sw.WriteLine("<th style=\"width:7%\" align=left class=SdsHeader>Spec. Ver.</th>");
sw.WriteLine("<th style=\"width:7%\" align=left class=SdsHeader>Rev. Level</th>");
sw.WriteLine("<th style=\"width:8%\" align=left class=SdsHeader>Rev. Date</th></tr>");
foreach (string file in genActive.Distinct())
{
string[] genOldDirectories = file.Split(Path.DirectorySeparatorChar);
string path = Path.GetDirectoryName(file);
string[] files = Directory.GetFiles(path);
var acro = ArdApp.Data.GeneralSpecification.GeneralSpecVersion.DataLoad(genOldDirectories[2].ToString(), Convert.ToInt32(genOldDirectories[3][0].ToString()), Convert.ToInt32(genOldDirectories[3][2].ToString() + genOldDirectories[3][3].ToString()));
sw.WriteLine("<tr><td id=\"idTDMenuTitle0008\">");
sw.WriteLine("<div id=\"idMenuTitle0008\" class=\"clsMenuTitle\" onclick=\"DoMenu(this)\">");
sw.WriteLine(genOldDirectories[2] + "</div>");
sw.WriteLine("<div id=\"idMenu0008\" class=\"clsMenu\">");
sw.WriteLine("<ul class=\"clsMenuBullets\">");
foreach (var fileName in files)
{
string[] fileDirectory = fileName.Split(Path.DirectorySeparatorChar);
sw.WriteLine("<li class=\"clsMenuItem\"><a class=\"clsMenuItem\" href=" + StripToWebFriendlyName(file) + ">" + StripToWebFriendlyName(fileDirectory[5]) + "</a></li>");
}
sw.WriteLine("</ul>");
sw.WriteLine("</div></td>");
sw.WriteLine("<td class=BodyText>" + acro.AcronymName + "</td>");
sw.WriteLine("<td class=BodyText>" + Convert.ToInt32(genOldDirectories[3][0].ToString()) + "</td>");
sw.WriteLine("<td class=BodyText>" + genOldDirectories[3][2].ToString() + genOldDirectories[3][3] + "</td>");
sw.WriteLine("<td class=BodyText>" + acro.RevisionDate + "</td>");
sw.WriteLine("</tr>");
}
sw.WriteLine("</table>");
sw.WriteLine("</Body>");
sw.WriteLine("</HTML>");
sw.Close();
}
What I tried:
....
foreach (var fileName in files)
{
string[] fileDirectory = fileName.Split(Path.DirectorySeparatorChar);
sw.WriteLine("<li class=\"clsMenuItem\"><a class=\"clsMenuItem\" href=" + StripToWebFriendlyName(file) + ">" + StripToWebFriendlyName(fileDirectory[5]) + "</a></li>");
}
sw.WriteLine("</ul>");
sw.WriteLine("</div></td>");
sw.WriteLine("<td class=BodyText>" + acro.AcronymName + "</td>");
sw.WriteLine("<td class=BodyText>" + Convert.ToInt32(genOldDirectories[3][0].ToString()) + "</td>");
sw.WriteLine("<td class=BodyText>" + genOldDirectories[3][2].ToString() + genOldDirectories[3][3] + "</td>");
sw.WriteLine("<td class=BodyText>" + acro.RevisionDate + "</td>");
sw.WriteLine("</tr>");
}
sw.WriteLine("var seen = {};");
sw.WriteLine("$('table tr').each(function() {");
sw.WriteLine("var txt = $(this).text();");
sw.WriteLine("if (seen[txt])");
sw.WriteLine(" $(this).remove();");
sw.WriteLine("else");
sw.WriteLine("seen[txt] = true;");
sw.WriteLine("});");
Looks like your just reading in file info and just want to display distinct files in your HTML display?
If this is still a c# question, consider just reading in the file info (full file path info) into a List<string> and then you could use linq "Distinct" to get your non-duplicated items and then output in html as needed.
Related
Hi i have problems getting my foreach to work. It only picks one node, in my simpel linq query. i actly dont no what the problem is, because i usede to be using Xmldocument and xmlnodelist. But i really want to learn do it using Linq, i cannot find anything on google why its not working, i allso tryede the expmales on these links.
http://www.dotnetcurry.com/linq/564/linq-to-xml-tutorials-examples
Simple LINQ to XML is not working
https://forums.asp.net/t/1378244.aspx?Linq+to+XML+query+how+to+get+all+elements+but+excluding+some+
http://www.c-sharpcorner.com/UploadFile/de41d6/learning-linq-made-easy-linq-to-xml-tutorial-3/
Both these examples only return, one xml node.
XElement ele = XElement.Load(filePath);
String aXmlString = ele.ToString(SaveOptions.DisableFormatting) + ele.Value;
foreach (XElement xNode in ele.Descendants("lakeringsdel"))
{
//litTest.Text = xNode.Element("lakeringsMetode").Value;
strData = "<table style='width:100%;' >"
+ "<tr>"
+ "<th>Nr.</th>"
+ "<th>Arbejdsbeskrivelse/Omfang</th>"
+ "<th>Metode</th>"
+ "<th>Ae</th>"
+ "</tr>"
+ "<tr>"
+ "<td>" + xNode.Element("ledenr").Value + "</td>"
+ "<td>" + xNode.Element("lakeringsDel").Value + "</td> "
+ "<td>" + xNode.Element("lakeringsMetode").Value + "</td> "
+ "<td>" + xNode.Element("arbejdsEnheder").Value + "</td> "
+ "</tr>"
+
"</table>";
}
next example
var test = "";
var q = from c in ele.Descendants("lakeringsdel")
select c.Element("lakeringsDel").Value;
foreach (string item in q)
{
test = item;
}
My xml document
<lakRapportDetaljer>
<aePrTime>10</aePrTime>
<fabrikatModelTekst>FORD FOCUS (CEW)</fabrikatModelTekst>
<kilometerStand>28205</kilometerStand>
<lakArbejde>2745.0</lakArbejde>
<lakIaltTotal>3610.05</lakIaltTotal>
<lakIndex>134</lakIndex>
<lakMaterialer>865.05</lakMaterialer>
<lakTimepris>450.0</lakTimepris>
<lakeringsMetode>2-LAGS METALLIC</lakeringsMetode>
<lakeringsMetode>DØRGREB LEVERES LAKE</lakeringsMetode>
<lakeringsdel>
<arbejdsEnheder>10.0</arbejdsEnheder>
<lakeringsDel>KOFANGER H B</lakeringsDel>
<lakeringsMetode>REPARATION LAK.PLAST</lakeringsMetode>
<ledenr>2584</ledenr>
</lakeringsdel>
<lakeringsdel>
<arbejdsEnheder>15.0</arbejdsEnheder>
<lakeringsDel>BAGSKÆRM HØJRE</lakeringsDel>
<lakeringsMetode>REP.LAK. <50%, METAL</lakeringsMetode>
<ledenr>3482</ledenr>
</lakeringsdel>
<lakeringsdel>
<arbejdsEnheder>5.0</arbejdsEnheder>
<lakeringsDel>SPECIALAFDÆKNING</lakeringsDel>
<lakeringsMetode>OVERFLADE LAKERING</lakeringsMetode>
<ledenr>1000</ledenr>
</lakeringsdel>
<miljoeLakMaterialerProcent>6</miljoeLakMaterialerProcent>
</lakRapportDetaljer>
I've tested your code,but I can't see any problem: it returns three nodes:
if you want to select all elements inside the 3 Xelement nodes "lakeringsdel", you could do :
var q = from c in ele.Descendants("lakeringsdel")
select c;
foreach (XElement item in q)
{
test = item.Value;
}
which gives :
or directly:
var q = ele.Descendants("lakeringsdel");
foreach (XElement item in q)
{
test = item.Value;
}
which gives the same result
or in 1 line:
ele.Descendants("lakeringsdel").ToList().ForEach(elem=>test =elem.Value);
but as said Reniuz in comment : you store only the last result in your "test" variable
if you want to store all results you could do:
List<string> test = new List<string>();
var q = from c in ele.Descendants("lakeringsdel")
select c.Element("lakeringsDel").Value;
foreach (string item in q)
{
test.Add(item);
}
or in 1 line:
test.AddRange(q);
In both examples you set the output strData and test every time you loop through your items. That results in handling nly the last item in your list.
Assuming you want to show a table with the results on your homepage you should change your first example to this
XElement ele = XElement.Load(filePath);
String aXmlString = ele.ToString(SaveOptions.DisableFormatting) + ele.Value;
strData = "<table style='width:100%;' >"
+ "<tr>"
+ "<th>Nr.</th>"
+ "<th>Arbejdsbeskrivelse/Omfang</th>"
+ "<th>Metode</th>"
+ "<th>Ae</th>"
+ "</tr>"
foreach (XElement xNode in ele.Descendants("lakeringsdel"))
{
//litTest.Text = xNode.Element("lakeringsMetode").Value;
strData += "<tr>"
+ "<td>" + xNode.Element("ledenr").Value + "</td>"
+ "<td>" + xNode.Element("lakeringsDel").Value + "</td> "
+ "<td>" + xNode.Element("lakeringsMetode").Value + "</td> "
+ "<td>" + xNode.Element("arbejdsEnheder").Value + "</td> "
+ "</tr>";
}
strData += "</table>";
I would recommend using a StringBuilder to build the string instead of +; whcih could look like this example.
StringBuilder strData = new StringBuilder("<table style='width:100%;'>");
strData.AppendLine("<tr>");
strData.AppendLine("<th>Nr.</th>");
I'm developing a LOB app targeted to windows store and I'd like to know what are the options to create custom reports for it. The user may want to, besides printing, export to PDF or CSV.
I don't know which API there is for windows store apps. Googling didn't help much.
If there isn't any tool to create the report, what would you guys suggest?
Looking the PrintSample from Microsoft, it prints the content of a grid component. I doubt how to set the size of page in this case so I can format the report properly.
Any help/idea is much appreciated.
Thanks!
I've committed to a client to build them a Windows Store App for their RT Tablet. I had no idea the technology was so... limited at the time. For example no System.Data, StreamWriter, and many other common business application functionalities are missing... Probably most surprising of all for me was a standard method of building reports. So far their appears to be no SSRS integration (Hopefully coming soon?). Looking at Crystal Reports they currently have no plans of extending to the Windows RT Platform.
I wasn't to impressed with Microsoft's Print sample either, which seemed like a hack more than anything. So I created a more suitable method for my needs. I am sure many of you have come up with your own methods including purchasing third party tools, but as for me I generated my custom reports through HTML and the current WindowsRT available SQLite methods (How Much I miss System.Data!). As mentioned StreamWriter doesn't seem really plausible with Windows RT so I did a little research for an alternative and this is what works for me:
private async void PrintEstimate()
{
// BUILD ESTIMATE WHICH IS AN HTML PAGE BECAUSE THEIR DID NOT APPEAR TO BE
// A WAY TO REALLY BUILD REPORTS FOR WINRT APPLICATIONS AT THIS POINT WITHOUT
// PURCHASING THRIRD PARTY TOOLS.
// Validate Estimate
// Are their values in the estimate list?
if (this.listServices.Items.Count < 1)
{
MessageDialog msgDialog = new MessageDialog("You must first add services before you can print an estimate.");
// Show the message dialog
await msgDialog.ShowAsync();
return;
}
if (string.IsNullOrEmpty(this.txtTotal1.Text))
{
MessageDialog msgDialog = new MessageDialog("You must first add the total before you can print an estimate.");
// Show the message dialog
await msgDialog.ShowAsync();
return;
}
var strAppPath = Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, #"EstimateReport\NewAPEMiniLogo.png");
var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "APE.db");
// ESTIMATE VARIABLES
string dtDateOfEstimate = Convert.ToString(this.dateEstimate.Date.ToString("MM/dd/yyyy"));
string strCustomerName = null;
string strCustomerAddress = null;
string strCustomerPhone = null;
string strCustomerNotes = null;
double totalCost = Convert.ToDouble(this.txtTotal1.Text);
double taxes = .08 * totalCost;
string strEstimateNote = this.txtNotes.Text;
string base64;
// THE WINRT Environment is very limited as far as accessing local resources... and from all that I have found
// Is purposely limited in allowing this to be done... thus here I am converting the image to a base64 string
//StorageFolder appFolder = ApplicationData.Current.LocalFolder;
StorageFolder appFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("EstimateReport");
StorageFile imageFile = await appFolder.GetFileAsync("NewAPEMiniLogo.png");
using (var stream = await imageFile.OpenAsync(FileAccessMode.Read))
{
var reader = new DataReader(stream.GetInputStreamAt(0));
var bytes = new byte[stream.Size];
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(bytes);
base64 = Convert.ToBase64String(bytes);
}
// IF NEW ESTIMATE
if (currentEstimateID == 0)
{
// CREATE/ INSERT NEW ESTIMATE
using (var db = new SQLite.SQLiteConnection(dbPath))
{
db.CreateTable<APE_Painting_App.DataAccess.Estimate>();
db.RunInTransaction(() => { db.Insert(new DataAccess.Estimate() { CustomerID = currentCustomerID, EstimateDate = Convert.ToDateTime(dtDateOfEstimate), TotalCost = totalCost, EstimateNotes = strEstimateNote }); });
string sql = "SELECT last_insert_rowid()";
currentEstimateID = db.ExecuteScalar<int>(sql);
db.Close();
}
}
else
{
// ELSE UPDATE CURRENT ESTIMATE
dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "APE.db");
using (var db = new SQLite.SQLiteConnection(dbPath))
{
// THE ONLY THREE ITEMS THAT SHOULD BE CHANGEABLE AT THE ESTIMATE LEVEL ARE TOTAL COST, ESTIMATE NOTES AND ESTIMATE DATE.
var objEstimate = db.Table<Estimate>().Where(c => c.EstimateID == currentEstimateID).Single();
objEstimate.EstimateDate = Convert.ToDateTime(dtDateOfEstimate);
objEstimate.TotalCost = totalCost;
objEstimate.EstimateNotes = strEstimateNote;
objEstimate.JobAwarded = this.chkJobAwarded.IsChecked.Value;
db.Update(objEstimate);
db.Close();
}
}
// GET CUSTOMER VALUES
using (var db = new SQLite.SQLiteConnection(dbPath))
{
var objCustomer = db.Table<Customer>().Where(c => c.CustomerID == currentCustomerID).Single();
strCustomerName = objCustomer.FirstName + " " + objCustomer.LastName;
strCustomerAddress = objCustomer.Address1 + " " + objCustomer.Address2 + " " + objCustomer.City + " " + objCustomer.State + " " + objCustomer.Zip;
strCustomerPhone = objCustomer.Phone1;
strCustomerNotes = objCustomer.CustomerNote;
db.Close();
}
StringBuilder sb = new StringBuilder();
sb.Append(#"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">" + "\r\n");
sb.Append(#"<!-- saved from url=(0016)http://localhost-->" + "\r\n");
sb.Append(#"<html xmlns=""http://www.w3.org/1999/xhtml"">" + "\r\n");
sb.Append(#"<head>" + "\r\n");
sb.Append(#"<meta http-equiv=""Content-Type"" content=""text/html; charset=utf-8"" />" + "\r\n");
sb.Append(#"<title>Service Estimate: A.P.E. Painting Inc.</title>" + "\r\n");
sb.Append(#"<style type='text/css' media='print'>.printbutton {visibility: hidden; display: none;}</style>" + "\r\n");
sb.Append(#"<style type=""text/css"">" + "\r\n");
sb.Append(#"body{font-family:""Palatino Linotype"", ""Book Antiqua"", Palatino, serif;}" + "\r\n");
sb.Append(#"#printablePage{ width:1000px; height:1300px; padding: 30px; position:relative; left:10px; top:10px; }" + "\r\n");
sb.Append(#"#headTitle{ font-size:24px; position:absolute; left:225px; top:15px;}" + "\r\n");
sb.Append(#"#reportName{ font-size:30px; position:absolute; left:850px; top:10px; color:#FFA61B;}" + "\r\n");
sb.Append(#"#companyBlock{ position:absolute; top:45px; left:225px;}" + "\r\n");
sb.Append(#"#footerNote{ font-size:16px;position:absolute; width:500px; left:150px; top:1135px; font-weight:bold;}" + "\r\n");
sb.Append(#"#logo{ position:absolute; top:20px; left:20px;}" + "\r\n");
sb.Append(#".customertable{font-size:14px;color:#333333;width:94%;border-width: 1px;border-color:#ebab3a;border-collapse:collapse;position:absolute;top:200px;}" + "\r\n");
sb.Append(#".apetable {font-size:14px;color:#333333;width:94%;border-width: 1px;border-color: #ebab3a;border-collapse: collapse; position:absolute; top: 350px;}" + "\r\n");
sb.Append(#".apetableB{font-size:14px;color:#333333;width:94%;border-width: 1px;border-color: #ebab3a;border-collapse: collapse; position:absolute; top: 1125px;}" + "\r\n");
sb.Append(#".apetableC{font-size:10px;color:#333333;width:94%;border-width: 1px;border-color: #ebab3a;border-collapse: collapse; position:absolute; top: 1236px;}" + "\r\n");
sb.Append(#"th {font-size:16px;background-color:#FFA61B;border-width: 1px;padding: 8px;border-style: solid;border-color: #ebab3a;text-align:left; color:#fff;}" + "\r\n");
sb.Append(#"tr {background-color:#FFF;}" + "\r\n");
sb.Append(#"td {font-size:12px;border-width: 1px;padding: 8px;border-style: solid;border-color: #FFA61B; height:20px;}" + "\r\n");
sb.Append(#".apetable tr:hover {background-color:#FFA61B;}" + "\r\n");
sb.Append(#".col1{width:80%;}" + "\r\n");
sb.Append(#".col1B{width:80%; border-left-color:#FFF; border-bottom-color:#FFF; border-top:none; text-align:right; font-size:16px; font-weight:bold;}" + "\r\n");
sb.Append(#".col1C{width:50%; font-size:12px; }" + "\r\n");
sb.Append(#".col2{width:20%; }" + "\r\n");
sb.Append(#"</style>" + "\r\n");
sb.Append(#"<script>function printDiv() {" + "\r\n");
sb.Append(#" window.focus(); window.print(); } " + "\r\n");
sb.Append(#"</script>" + "\r\n");
sb.Append(#"</head>" + "\r\n");
sb.Append(#"<body>" + "\r\n");
sb.Append(#"<input style = 'position:absolute; width: 150px; height:75px; z-index: 99;' type='button' class='printbutton' onClick='printDiv()' value='Print Report' />" + "\r\n");
sb.Append(#"<div id=""printablePage"">" + "\r\n");
sb.Append(#"<h1 id=""headTitle"">A.P.E. Painting Inc.</h1>" + "\r\n");
sb.Append(#"<h1 id=""reportName"">" + this.pageTitle.Text + #"</h1>" + "\r\n");
sb.Append(#"<h3 id=""companyBlock"">" + "\r\n");
sb.Append(#"30809 NE Coyote Lane <br/>" + "\r\n");
sb.Append(#"Yacolt, WA 98675 <br/>" + "\r\n");
sb.Append(#"(360) 263-7699 <br/>" + "\r\n");
sb.Append(#"<em> WA State Lic. & Reg. #APEPAI*011QQ</em>" + "\r\n");
sb.Append(#"</h3>" + "\r\n");
//sb.Append(#"<img id= ""logo"" src=""" + strAppPath + #""" width=""197"" height=""148"" alt=""APE LOGO"" />" + "\r\n");
sb.Append("<img src=\"data:image/png;base64,");
sb.Append(base64);
sb.Append("\" />");
sb.Append(#"<table class=""customertable"" border=""1"">" + "\r\n");
sb.Append(#"<tr><td> <strong>Estimate Date:</strong> " + dtDateOfEstimate + " | <strong>Customer:</strong> " + strCustomerName + " | <strong>Customer Phone:</strong> " + strCustomerPhone + " </td></tr>" + "\r\n");
sb.Append(#"<tr><td> <strong>Customer Address:</strong> " + strCustomerAddress + " </td></tr>" + "\r\n");
sb.Append(#"<tr><td> <strong>Project Notes:</strong> " + strEstimateNote + " </td></tr>" + "\r\n");
sb.Append(#"</table>" + "\r\n");
sb.Append(#"<table class=""apetable"" border=""1"">" + "\r\n");
sb.Append(#"<tr><th class=""col1"">Services</th></tr>" + "\r\n");
// Get Count of Estimate Items
int intEstimateLines = this.listServices.Items.Count;
// DELETE ALL PREVIOUS SERVICE LINES FOR THIS ESTIMATE IF ANY EXIST
using (var db = new SQLite.SQLiteConnection(dbPath))
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection(dbPath);
var query = conn.Table<EstimateDetails>().Where(x => x.EstimateID == currentEstimateID);
var result = await query.ToListAsync();
foreach (var item in result)
{
// FIRST DELETE ALL ESTIMATE DETAIL RECORDS
// GET CURRENT ESTIMATE ID
int estimateDetailID = item.EstimateDetailID;
try
{
db.Execute("DELETE FROM EstimateDetails WHERE EstimateDetailID = ?", estimateDetailID);
}
catch (Exception ex)
{
}
}
}
// LOOP 20 Times TO CREATE THE STATIC LINES IN THE INVOICE WHETHER THEIR IS A SERVICE OR NOT. ALSO:
// INSERT SERVICES/ LOOP THORUGH SERVICES ARRAY TO OBTAIN VALUES
for (int i = 0; i < 20; i++)
{
// INSERT RECORD TO DATABASE IF NECESSARY FIELDS HAVE VALUE
if (i >= intEstimateLines)
{
// NO SERVICES OR COST JUST ADD EMPTY SPACE ON REPORT
sb.Append(#"<tr><td class=""col1""> </td></tr>" + "\r\n");
}
else
{
this.listServices.SelectedIndex = i;
string currentValue = this.listServices.SelectedItem.ToString();
using (var db = new SQLite.SQLiteConnection(dbPath))
{
db.CreateTable<APE_Painting_App.DataAccess.EstimateDetails>();
db.RunInTransaction(() => { db.Insert(new DataAccess.EstimateDetails() { EstimateID = currentEstimateID, EstimateLineItem = currentValue }); });
// FILL REPORT WITH CORRESPONDING VALUES
sb.Append(#"<tr><td class=""col1""> " + currentValue + #" </td></tr>" + "\r\n");
}
}
}
sb.Append(#"</table>" + "\r\n");
sb.Append(#"<table class=""apetableB"" border=""1"">" + "\r\n");
sb.Append(#"<tr><td class=""col1B"">Sub Total:</td><td class=""col2"" style="" text-align:Left;"">" + String.Format("{0:C}", totalCost) + #" </td></tr>" + "\r\n");
sb.Append(#"<tr><td class=""col1B""> Taxes:</td><td class=""col2"" style="" text-align:Left;""> " + String.Format("{0:C}", taxes) + #" </td></tr>" + "\r\n");
sb.Append(#"<tr><td class=""col1B"">Total:</td><td class=""col2"" style="" text-align:Left;"">" + String.Format("{0:C}", (taxes + totalCost)) + #" </td></tr>" + "\r\n");
sb.Append(#"</table>" + "\r\n");
sb.Append(#"<div id=""footerNote"">We propose to furnish material and labor - complete in accordance with the above specifications, for the sum of:<br /><br />Method of Payment:</div>" + "\r\n");
sb.Append(#"<table class=""apetableC"" border=""1"">" + "\r\n");
sb.Append(#"<tr>" + "\r\n");
sb.Append(#"<td class=""col1C"">All material is guaranteed to be as specified. All work to be completed in a workman like manner according to standard practices. Any alteration or deviation from above specifications involving extra costs will be executed only upon written orders, and will become an extra charge over and above the estimate. All agreements contingent upon strikes, accidents or delays beyond our control. Owner to carry fire, tornado and other necessary insurance. Our workers are fully covered by Workmans Compensation Insurance. </td>" + "\r\n");
sb.Append(#"<td class=""colC""><span style=""font-weight:bold;"">Acceptance of Proposal- </span>The above prices, specifications and conditions are satisfactory and are hereby accepted. Your are authorized to do the work as specified. Payment will be made as outlined above. <span style=""font-weight:bold;"">Date of Acceptance:_______________________ </span><br /><br /><br /> <span style=""font-weight:bold;"">Signature:________________________________________________________________________</span></td></tr>" + "\r\n");
sb.Append(#"</table>" + "\r\n");
sb.Append(#"</div>" + "\r\n");
sb.Append(#"<body>" + "\r\n");
sb.Append(#"</body>" + "\r\n");
sb.Append(#"</html>" + "\r\n");
// Create a file in local storage
var folder = ApplicationData.Current.LocalFolder;
var file = await folder.CreateFileAsync("APE_Printable_Estimate.html", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(file, sb.ToString());
string strURL = #"file:/// " + file.Path.ToString(); //
// OPEN FILE
await Windows.System.Launcher.LaunchFileAsync(file);
}
Unfortunately there is no free library (tool/sdk) for generating PDF/Excel reports in Windows Store App now. But if you have money for buying - check PDFTron and Syncfusion
I'm trying to write to a CSV file from a list using the LinqToCSV library found on http://www.codeproject.com/Articles/25133/LINQ-to-CSV-library#Installation.
When I try and run my program I keep getting a CsvColumnAtrributeRequiredException exception. So it's not filling a CSV file.
Here is my code:
private void button1_Click(object sender, EventArgs e) // merge files button
{
if(System.IO.File.Exists("OUTPUT.csv"))
{
System.IO.File.Delete("OUTPUT.csv");
output = new System.IO.StreamWriter("OUTPUT.csv");
}
else
{
output = new System.IO.StreamWriter("OUTPUT.csv");
}
String[] parts = new String[1000];
String[] parts2 = new String[1000];
parts = File.ReadAllLines(textBox1.Text); //gets filepath from top textbox
parts2 = File.ReadAllLines(textBox2.Text); //gets filepath from middle textbox
String[] head = File.ReadAllLines(headingFileBox.Text); //header file array
//merging the two files onto one list, there is no need to merge the header file because no math is being
//computed on it
var list = new List<String>();
list.AddRange(parts);
list.AddRange(parts2);
//foreach loop to write the header file into the output file
foreach (string h in head)
{
output.WriteLine(h);
}
//prints 3 blank lines for spaces
output.WriteLine();
output.WriteLine();
output.WriteLine("LEASE NAME" + "," + "FIELD NAME" + "," + "RESERVOIR" + "," + "OPERATOR" + "," +"COUNTY" + "," + "ST" + "," + "MAJO" + "," + "RESV CAT" + "," + "DISCOUNT RATE"
+ "," + "NET OIL INTEREST" + "," + "NET GAS INTEREST" + "," + " WORKING INTEREST" + "," + "GROSS WELLS" + "," + "ULT OIL" + "," + "ULT GAS" + "," + "GROSS OIL" + ","
+ "GROSS NGL" + "," + "GROSS GAS" + "," + "NET OIL" + "," + "NET GAS" + "," + "NET NGL" + "," +"REVENUE TO INT." + "," + "OPER. EXPENSE" + "," + "TOT INVEST." + ","
+ "REVENUE OIL" + "," + "REVNUE GAS" + "," + "OPERATING PROFIT" + "," + "REVENUE NGL" + "," + "DISC NET INCOME" + "," + "SEQ" + "," + "WELL ID" + "," + "INC ASN" + ","
+ "LIFE YEARS" + "," + "OWN QUAL" + "," + "PRODUCTION TAX" + "," + "AD VALOREM TAX");
output.WriteLine();
output.WriteLine();
String[] partsComb = list.ToArray(); // string array that takes in the list
Array.Sort(partsComb);
CsvFileDescription outputFileDescription = new CsvFileDescription
{
SeparatorChar = '\t',
FirstLineHasColumnNames = false,
};
CsvContext cc = new CsvContext();
cc.Write(partsComb ,output, outputFileDescription);
I'm just trying to get this up and running to output it correctly to a CSV file. Any help would be greatly appreciated.
Your code doesn't appear to be using any of the features of Linq2Csv.
You get the error because you're just trying to write a string out which doesn't have csvcolumn attribute.
Why do you think you need linq2csv? From your code you read in 2 files sort the lines from those files then try to write the result back out. You're not using any of Linq2csv's features. You could just write this result straight to a file & not use linq2csv.
Alternatively, create a class that matches the data you are reading, then follow the instructions in the article to read the file into a list of that class. merge & write back out again using linq2csv.
More Info
This line from the article reads the data in
IEnumerable<Product> products = cc.Read<Product>("products.csv", inputFileDescription);
You need to do this for each file you want to read into 2 lists eg parts & parts2 from your code.
having done this, follow the example for writing a file, but pass parts.union(parts2) instead of products2.
cc.Write(products2, "products2.csv", outputFileDescription);
I am trying to set the innerhtml of an html select tag but I cannot set this feature;therefor,I need to use the outerhtml feature.This way,not only is my code HARDCODE ,but also it is preposterous.I have already read 'InnerHTML IE 8 doesn't work properly? Resetting form',it did not help though.
I would really appreciate it if you tell me how to set the innerhtml feature of an html select tag.
My C# code:
public void SetDefaultValue(string ControlID, string ControlValue)
{
System.Windows.Forms.HtmlDocument doc = webBrowser1.Document;
HtmlElement HTMLControl = doc.GetElementById(ControlID);
string ListResult;
string ListInnerHTML = "";
ListInnerHTML += "<OPTION value = " + LstString + ">" + LstString + "</OPTION>";
ListResult = "<SELECT id = " + '"' + HTMLControl.Id + '"' + " type = " + '"' + HTMLControl.GetAttribute("type") + '"' + " title = " + '"' +
HTMLControl.GetAttribute("title") + '"' + " name = " + '"' + HTMLControl.Name + '"' + " value = " + '"' + HTMLControl.GetAttribute("value") +
'"' + " size = \"" + HTMLControl.GetAttribute("size") + '"' + HTMLControl.GetAttribute("multiple").ToString() + "\">" + ListInnerHTML + "</SELECT>";
HTMLControl.OuterHtml = ListResult;
}
or
string _lsthtml = _htmlel.OuterHtml;
string[] _parts = ControlValue.Split(new char[] { ',' });
string _lstinner = "";
foreach (string _lst in _parts)
_lstinner += "<option value=" + _lst + ">" + _lst + "</option>";
_lsthtml = _lsthtml.Insert(_lsthtml.IndexOf(">") + 1, _lstinner);
_htmlel.OuterHtml = _lsthtml;
This code works but I need something efficient and clean.
The ReturnControlType function returns the type of an html tag.
This is an official Internet Explorer bug:
BUG: Internet Explorer Fails to Set the innerHTML Property of the Select Object.
One workaround
You may try adding one of the following meta tags in your document's head:
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
or
<meta http-equiv="X-UA-Compatible" content="IE=10" />
You should also properly format the option tag's value attribute (enclose LstString in '):
ListInnerHTML += "<OPTION value='" + LstString + "'>" + LstString + "</OPTION>";
A more reliable solution
As the fixes above might be a workaround for your code, I would suggest to use a more reliable approach. Consider adding a reference to Microsoft.mshtml to your project and modifying your method like this:
// add this to the top of the file containing your class
using mshtml;
public void SetDefaultValue(string ControlID, string ControlValue)
{
System.Windows.Forms.HtmlDocument doc = webBrowser1.Document;
IHTMLDocument2 document = doc.DomDocument as IHTMLDocument2;
var sel = doc.GetElementById(ControlID);
HTMLSelectElement domSelect = (HTMLSelectElement)sel.DomElement;
domSelect.options.length = 0;
HTMLOptionElement option;
// here you can dynamically add the options to the select element
for (int i = 0; i < 10; i++)
{
option = (HTMLOptionElement)document.createElement("option");
option.text = String.Format("text{0}", i);
option.value = String.Format("value{0}", i);
domSelect.options.add(option, 0);
}
}
I really don't know why innerHTML is not working for you.
If it just dosen't you could try an alternative:
http://innerdom.sourceforge.net/
demo
In this thread it is sugested you use the items collection of a control
How to add items to dynamically created select (html) Control
refer to this page for a complete example:
http://msdn.microsoft.com/en-us/library/system.web.ui.htmlcontrols.htmlselect.items.aspx
I'm currently working on an ASP.NET project where I'm using the Google Maps API to show a marker for every company that's registrated in the database.
Everything works just fine, but when I click on a marker the tooltip/dialogbox for the last company in my company list always shows up and not the actualy company mark that's been clicked on.
I can't really get my head around why it is always the last marker that shows up. Here's my updated code:
JavaScript.Text = #"<script type='text/javascript'>
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(56.4, 10.57983), 9);
map.enableScrollWheelZoom();
}
}
</script> ";
foreach (MemberProfile m in relatedMembers)
{
XmlDocument doc = new XmlDocument();
string address = m.Address;
string zip = m.Zip;
string city = m.City;
string navn = m.Name;
string tlf = m.Phone;
doc.Load("http://maps.googleapis.com/maps/api/geocode/xml?address=" + zip + "+" + city + "+" + address + "+DK&sensor=true&key=ABQIAAAAEaY4JLb9fZFGMlDKuMUlWBRSvyGIkBO7X03pzlT7Z30EPXHR8BS0rXL_ShFm2gc79lZTw2Zak88wng");
XmlNode latNode = doc.SelectSingleNode("GeocodeResponse/result/geometry/location/lat/text()");
XmlNode lonNode = doc.SelectSingleNode("GeocodeResponse/result/geometry/location/lng/text()");
if (latNode != null && lonNode != null)
{
JSAddMarkers.Text += #"<script type='text/javascript'>
var marker = new GMarker(new GLatLng(" + latNode.Value + "," + lonNode.Value + ")); "
+ "var html = '<b>" + navn + "</b><br />" + address + "<br /> " + zip + " " + city + "<br />" + tlf + "'; " + "GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(html); });"
+ "map.addOverlay(marker);"
+ "</script>";
}
If any of you out there can spot the reason why, I would be happy to hear from you! Any help/hint is appreciated :-)
All the best,
Bo
try this
var point =new GLatLng(" + latNode.Value + "," + lonNode.Value + ");
var marker = createMarker(point, address,zip,city,navn);
map.addOverlay(marker);
function createMarker(point, address, zip,city, navn) {
var marker = new GMarker(point, customIcons[type]);
var html = "Address:<b style='padding-left:6px'>" + address+ "</b><br/>zip:<b style='padding-left:6px'>"+ zip+ "</b><br/>city:<b style='padding-left:6px'>"+ city+ "</b>";
GEvent.addListener(marker, 'mouseover', function() {
marker.openInfoWindowHtml(html);
});
GEvent.addListener(marker, "mouseout", function() {
marker.closeInfoWindow();
});
return marker;
}