for effective debugging of my program, I tried to write function that gets an exception and emails me detailed reporting about the exception.
c# code:
public static bool SendExceptionMail(Exception ex, string[] mail, string title)
{
StringBuilder builder = new StringBuilder();
builder.Append("<table>");
var st = new StackTrace(ex, true);
builder.Append("<tr><td colspan='3'><h3>" + ex.GetType().Name + "</h3></td></tr>");
builder.Append("<tr><td style='border: 1px solid #d8d8d8'>function name</td><td style='border: 1px solid #d8d8d8'>function path</td><td style='border: 1px solid #d8d8d8'>line number</td></tr>");
StackFrame[] frames = st.GetFrames();
for (int i = 0; i < frames.Length; i++)
{
builder.Append("<tr>");
var frame = st.GetFrame;
var line = frame.GetFileLineNumber();
var name = frame.GetFileName();
var functionName = frame.GetMethod().Name;
builder.Append("<tr><td style='border: 1px solid #d8d8d8'>" + functionName + "</td><td style='border: 1px solid #d8d8d8'>" + name + "</td><td style='border: 1px solid #d8d8d8'>" + line + "</td></tr>");
builder.Append("</tr>");
}
builder.Append("<tr><td colspan='3'>" + getInnerException(ex) + "</td></tr>");
builder.Append("<tr><td colspan='3'>" + ex.Data + "</td></tr>");
builder.Append("<tr><td colspan='3'>" + ex.StackTrace + "</td></tr>");
builder.Append("<tr><td colspan='3'>" + DateTime.Now + "</td></tr>");
builder.Append("</table>");
return MailBll.Send("Exception in WS - " + frames[0].GetMethod().Name + " function", builder.ToString(), mail);
}
private static string getInnerException(Exception ex)
{
StringBuilder str = new StringBuilder();
do
{
str.Append(ex.Message + "<br/>";
ex = ex.InnerException;
} while (ex != null);
return str.ToString();
}
Clearing function:
public TranStatus Clearing(Entities.Tran tran, int projectId, string Link = null)
{
string d = DateTime.Now.ToString();
try
{
sendTranDetails(tran, projectId, d);
if (!string.IsNullOrEmpty(tran.Token) && !string.IsNullOrEmpty(tran.CreditNum))
{
tran.Token = "";
}
tran.Ip = "";
if ((string.IsNullOrEmpty(tran.CreditNum) || tran.CreditNum.Length < 7) && string.IsNullOrEmpty(tran.Token))
{
return db.getCardErrorMassege("478");
}
if (!string.IsNullOrEmpty(tran.CreditNum) && tran.CreditNum.Length > 4)
{
if (tran.CreditNum.Substring(0, 4) == "0404" || tran.CreditNum.Substring(0, 4) == "0403")
{
tmobile m = db.Mobiles.GetById(int.Parse(tran.Comment2));
return db.getCardErrorMassege("479");
}
}
tterminal terminal;
tproject p = db.GetProjectById(projectId);
tran.ProjectNumber = p.sNumProject;
terminal = db.GetterminalByProjectId(projectId);
tran.Total = (int)tran.Total;
tran.CompanyId = (int)p.iCompanyId;
fixTran(tran);
string intot = Dal.Transaction(terminal.sTerminalId.Substring(0, 7), PasswordBll.DecodeFrom64(terminal.sPasswordService), tran);
string creditStatus = db.getcreditStatusById(intot);
sendEmailTran(d, intot + " - " + creditStatus + "<br/>");
return db.getCardErrorMassege(intot.Substring(0, 3));
}
catch (Exception ex)
{
MailBll.SendExceptionMail(ex);
return db.getCardErrorMassege("484");
}
}
the function works ok, but there are some functions that I cannot get the original function that the exception was thrown from it.
for example: when I get exception of "IndexOutOfRangeException" I got this mail:
but I don't see which line in Clearing function threw the exception and which file it was.
what can be the reason?
Debug or Release build?
If you are using a optimised (release) build, then the compiler is allowed to remove simple functions and in-line them. At this point, they won't have a stack frame. To get a good stack trace, you need to make sure no optimisations are enabled.
Related
I am using Microsoft.Office.Interop.Outlook and I am trying to loop trough all the appointments that match a particular set of conditions:
To reduce the items I limit the search between two knows maximum dates
It has to contain an "ID"
Beside the additional regex that I don't know if it can be fitted in the .Restrict, the foreach loop interrupts at the first entry
DateTime start = DateTime.Now.AddDays(-1);
string filter1 = "[Start] >= '" + start.ToString("g") + "' AND [End] <= '" + DateTime.MaxValue.ToString("g") + "'";
Outlook.Items calendarItems = personalCalendar.Items.Restrict(filter1);
calendarItems.IncludeRecurrences = true;
calendarItems.Sort("[Start]", Type.Missing);
string filter3 = "#SQL=" + "\"" + "urn:schemas:httpmail:subject" + "\"" + " LIKE '%" + AppCode + "%'";
Outlook.Items restrictedItems = calendarItems.Restrict(filter3);
bool error_free = true;
foreach (Outlook.AppointmentItem apptItem in restrictedItems)
{
MessageBox.Show(apptItem.Subject);
try
{
if (Regex.IsMatch(apptItem.Subject, #"^.*##ManaOrdini\d{1,}##.*$"))
{
apptItem.Move(newCalendarFolder);
}
}
catch (System.Exception ex)
{
MessageBox.Show("Si è verificato un errore durante la creazione dell'appuntamento. Errore: " + ex.Message);
error_free = false;
}
}
Can anybody explain me why? Do I have to add a goto method to iterate untill no entry found?
EDIT
The variable restrictedItems contains the following entries:
Subject "Reminder Ordine Numero:1\t##ManaOrdini1#" System.String
Subject "Reminder Ordine Numero:1\t##ManaOrdini##" System.String
Subject "Reminder Ordine Numero:1\t##ManaOrdini1222##" System.String
Subject "Reminder Ordine Numero:1\t##ManaOrdini1##" System.String
EDIT 2
Ended up with this, basically I had to split in two parts:
Clone the results of the filters
Loop and move
DateTime start = DateTime.Now.AddDays( - 2);
string filter1 = "[Start] >= '" + start.ToString("g") + "' AND [End] <= '" + DateTime.MaxValue.ToString("g") + "'";
Outlook.Items calendarItems = personalCalendar.Items.Restrict(filter1);
calendarItems.IncludeRecurrences = true;
calendarItems.Sort("[Start]", Type.Missing);
string filter3 = "#SQL=" + "\"" + "urn:schemas:httpmail:subject" + "\"" + " LIKE '%" + AppCode + "%'";
Outlook.Items restrictedItems = calendarItems.Restrict(filter3);
bool error_free = true;
int c = 0;
List < Outlook.AppointmentItem > listaApp = new List < Outlook.AppointmentItem > ();
foreach(Outlook.AppointmentItem apptItem in restrictedItems) {
if (Regex.IsMatch(apptItem.Subject, #"^.*##ManaOrdini\d{1,}##.*$")) {
listaApp.Add(apptItem);
c++;
}
}
for (int i = 0; i < c; i++) {
try {
listaApp[i].Move(newCalendarFolder);
}
catch(System.Exception ex) {
MessageBox.Show("Si è verificato un errore durante la creazione dell'appuntamento. Errore: " + ex.Message);
error_free = false;
}
}
I am trying to generate excel with following code
public void GenerateExcel(string reportName, DataTable dt)
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.Buffer = true;
Response.ContentType = "application/ms-excel";
Response.Write(#"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">");
Response.AddHeader("Content-Disposition", "attachment;filename= " + reportName + ".xls");
Response.Charset = "utf-8";
Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
StringWriter ws = new StringWriter();
ws.Write("<font style='font-size:10.0pt; font-family:Calibri;'>");
// ws.Write("<BR><BR><BR>");
//sets the table border, cell spacing, border color, font of the text, background, foreground, font height
ws.Write("<Table border='1' bgColor='#ffffff' " +
"borderColor='#000000' cellSpacing='0' cellPadding='0' " +
"style='font-size:10.0pt; font-family:Calibri; background:white;'>");
string strBoldCell = "<TD bgColor='#c9c7c3' style=\"font-weight: bold\">{0}</TD>";
string strRedCell = "<TD style=\"background-color:#ff4d4d\">{0}</TD>";
string strCell = "<TD>{0}</TD>";
string strColSpan = "<TD colspan={0} style=\"font-weight: bold\">{1}</TD>";
int r;
int c;
if (dt.Rows.Count > 0)
{
try
{
ws.Write("<TR>");
for (c = 0; c < dt.Columns.Count; c++)
{
ws.Write(string.Format(strBoldCell, dt.Columns[c].ColumnName).Replace("_", ""));
}
ws.Write("</TR>");
ws.Write("\n");
for (r = 0; r < dt.Rows.Count; r++)
{
ws.Write("<TR>");
for (c = 0; c < dt.Columns.Count; c++)
{
if (string.IsNullOrEmpty(dt.Rows[r][dt.Columns[c].ColumnName].ToString()) == false)
{
if (dt.Rows[r]["Comment"].ToString() != null && dt.Rows[r]["Comment"].ToString() != "")
{
ws.Write(string.Format(strRedCell, dt.Rows[r][dt.Columns[c].ColumnName].ToString().Replace('_', ' ')));
}
else
{
ws.Write(string.Format(strCell, dt.Rows[r][dt.Columns[c].ColumnName].ToString().Replace('_', ' ')));
}
}
else
{
if (dt.Rows[r]["Comment"].ToString() != null && dt.Rows[r]["Comment"].ToString() != "")
{
ws.Write(string.Format(strRedCell, " "));
}
else
{
ws.Write(string.Format(strCell, " "));
}
}
}
ws.Write("</TR>");
ws.Write("\n");
}
}
catch (Exception ex)
{
throw ex;
}
}
else
{
ws.Write("<Tr>");
ws.Write(string.Format(strColSpan, 10, "No records found"));
ws.Write("</Tr>");
}
ws.Write("</Table>");
ws.Write("</Font>");
Response.Write(ws.ToString());
Response.Flush();
Response.End();
}
by calling above method in main method as follows
if (Cnt != 0)
{
TempData["Error"] = "There were issues with the Excel Import: Total Records: " + result.Rows.Count+" Error Row Count: "+Cnt;
}
else
{
TempData["Error"] = "No error found in given excel: Total Records: " + result.Rows.Count;
}
GenerateExcel("OutputFile" + DateTime.Now.ToString("MMddyyyyhhmmss"), result);
return View();
also trying to pass Tempdata to view but the problem is excel is generating successfully but tempdata does not showing anything in view.
if i comment the code of calling GenerateExcel method tempdata is perfectly showing on view..why this is happening?
Please Try moving calling function before setting tempdata like:
GenerateExcel("OutputFile" + DateTime.Now.ToString("MMddyyyyhhmmss"), result);
if (Cnt != 0)
{
TempData["Error"] = "There were issues with the Excel Import: Total Records: " + result.Rows.Count+" Error Row Count: "+Cnt;
}
else
{
TempData["Error"] = "No error found in given excel: Total Records: " + result.Rows.Count;
}
return View();
When Im trying to generate HTML Formatted Result set and sending the resultset as Email using SMTPsettings,Its working fine in Outlook but the same htmlformat is not displayed in gmail It displays as a plain Text.
public void GenerateRpt()
{
DataSet ds= new DataSet();
//Result set is assigned to the dataset object.
if ds[0].Rows.Count == 0)
return;
else
{
try
{
StringBuilder builder = new StringBuilder();
builder.Append("<html xmlns='http://www.w3.org/1999/xhtml'>");
builder.Append("<head>");
builder.Append("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />");
builder.Append(" <style type='text/css'> #page {} table { border-collapse: collapse;border-spacing: 0;empty-cells: show} ");
builder.Append(" .Default { font-family: Calibri;background-color: transparent;border-style: none;vertical-align: bottom;margin-left: 0in;");
builder.Append(" writing-mode: page;color: #000000;font-size: 11pt; font-style: normal;text-shadow: none; text-decoration: none ! important;font-weight: normal;}");
builder.Append(" .ce2 { background-color: #95b3d7;border-width: 0.0349cm;border-style: solid;border-color: #000000;color: #000000;font-size: 11pt;");
builder.Append("font-style: normal;font-weight: bold;margin-left: 0in;text-shadow: none;font-family: Calibri;text-decoration: none ! important;");
builder.Append("vertical-align: middle;writing-mode: page;text-align: center ! important;}");
builder.Append(" .ce5 { background-color: transparent;border-width: 0.0349cm;border-style: solid;border-color: #000000;color: #000000;font-size: 11pt;");
builder.Append("font-style: normal;font-weight: normal;margin-left: 0in;text-shadow: none;font-family: Calibri;text-decoration: none ! important;");
builder.Append("vertical-align: middle;writing-mode: page;text-align: center ! important;}");
builder.Append(" .ce6 { background-color: #a6a6a6;border-width: 0.0349cm;border-style: solid;border-color: #000000;color: #000000;font-size: 11pt;");
builder.Append("font-style: normal;font-weight: bold;margin-left: 0in;text-shadow: none;font-family: Calibri;text-decoration: none ! important;");
builder.Append("vertical-align: middle;writing-mode: page;text-align: center ! important;}");
builder.Append(" .ce13 { background-color: transparent;border-width: 0.0349cm;border-style: solid;border-color: #000000;color: #000000;font-size: 11pt;");
builder.Append("font-style: normal;font-weight: normal;margin-left: 0in;text-shadow: none;font-family: Calibri;text-decoration: none ! important;");
builder.Append("vertical-align: bottom;writing-mode: page;}");
builder.Append(" .contentText {font-size: 11pt;font-weight: normal;font-style: normal;font-style: Calibri;font-weight: bold;COLOR: #cccccc;");
builder.Append("</style>");
builder.Append("</head>");
builder.Append("<body>");
builder.Append("<table border='0' cellpadding='1' cellspacing='1' width='70%'> ");
builder.Append("<tr class='ro1'><td colspan='4'><b><p>RPT NAME</p></b></td></tr>");
builder.Append("<tr class='ro1'>");
builder.Append("<td class='ce2'><p>COL1</p></td>");
builder.Append("<td class='ce2'><p>COL2</p></td>");
builder.Append("<td class='ce2'><p>COL3</p></td>");
builder.Append("<td class='ce2'><p>COL4</p></td>");
builder.Append("</tr>");
string tempdrow = string.Empty;
int i;
for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
builder.Append("<td class='ce5'>");
builder.Append("<p>" + ds.Tables[0].Rows[i]["Col1"].ToString() + "</p>");
builder.Append("</td>");
builder.Append("<td class='ce13' style='text-align: center'>");
builder.Append("<p>" + ds.Tables[0].Rows[i]["Col2"].ToString() + "</p>");
builder.Append("</td>");
builder.Append("<td class='ce13' style='text-align: center'>");
builder.Append("<p>" + ds.Tables[0].Rows[i]["Col3"].ToString() + "</p>");
builder.Append("</td>");
builder.Append("<td class='ce13' style='text-align: center'>");
builder.Append("<p>" + ds.Tables[0].Rows[i]["Col4"].ToString() + "</p>");
builder.Append("</td>");
builder.Append("</tr>");
}
// When No more records in the Dataset show the Grand Total.
builder.Append("<tr class='ro2'>");
builder.Append("<td class='ce13' style='text-align: center'>");
builder.Append("<b><p>GRAND TOTAL </p></b>");
builder.Append("</td>");
builder.Append("<td class='ce13' style='text-align: center'>");
builder.Append("<p>" + ds.Tables[0].Rows[i - 1]["Col2"].ToString() + "</p>");
builder.Append("</td>");
builder.Append("<td class='ce13' style='text-align: center'>");
builder.Append("<p>" + ds.Tables[0].Rows[i - 1]["Col3"].ToString() + "</p>");
builder.Append("</td>");
builder.Append("<td class='ce13' style='text-align: center'>");
builder.Append("<p>" + ds.Tables[0].Rows[i - 1]["Col4"].ToString() + "</p>");
builder.Append("</td>");
builder.Append("</tr>");
builder.Append("</table>");
string sVehRejsubject = System.Configuration.ConfigurationManager.AppSettings["Subject"].ToString();
sendmail(builder.ToString(), sVehRejsubject);
}
catch (Exception ex)
{
ex.Message();
}
}
}
// Mail Sending Part
void sendmail(string strResultSet,string strRptType)
{
try
{
if (strResultSet.ToString() != "")
{
string strMessage1 = string.Empty, TestEmp = "Mani";
strMessage1 = strResultSet.ToString();
strMessage1 += "<br><br><font color='blue'><b>Date:</b></font> " + DateTime.Now.ToString("dd/MM/yyyy") + "<BR>";
strMessage1 += "<br>Regards,<BR><BR>";
strMessage1 += TestEmp + "</b><br>";
<BR></td></tr></table></body></html>";
MailMessage mail = new MailMessage();
//SMTP SETTINGS DEFINED IN APP.CONFIG FILE
System.Net.Mail.SmtpClient _client = new System.Net.Mail.SmtpClient();
string sFrom = System.Configuration.ConfigurationManager.AppSettings["emailFrom"].ToString();
string sTo = System.Configuration.ConfigurationManager.AppSettings["emailTo"].ToString();
string sCC = System.Configuration.ConfigurationManager.AppSettings["emailCC"].ToString();
string sBCC = System.Configuration.ConfigurationManager.AppSettings["emailBCC"].ToString();
string sDisplayName = System.Configuration.ConfigurationManager.AppSettings["emailFromDisplayName"].ToString();
mail.From = new MailAddress(sFrom, sDisplayName);
mail.To.Add(new MailAddress(sTo));
if (sCC.ToString() != "")
{
mail.CC.Add(sCC);
}
if (sBCC.ToString() != "")
{
mail.Bcc.Add(sBCC);
}
mail.IsBodyHtml = true;
mail.Subject = strRptType + " AS ON - " + System.DateTime.Now.ToString("dd/MM/yyyy");
mail.Body = strMessage1;
_client.Send(mail);
}
}
catch (Exception ex)
{
Ex.Message();
return;
}
}
Email providers, does not allow the entire spectrum of html tags to be included in a message. In case you try to include an unsupported tag it will be ignored or automatically changed to another tag.
It is the same with unsupported css attributes.
For example <br/> is not allowed and will be ignored
What you should do is use universally supported Html tags only.
I've found this page which lists the universally supported html tags and css attributes
Good luck !
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
Neither of these methods are working for me and for the life of me I can't figure out why. Been googling like crazy and prowling this site, which is where I found the commented method below.
No matter what I do, the content displayed is NOT updating :'(
ANY help would be appreciated.. I'm at my wits' end.
private void Form1_Shown(object sender, EventArgs e)
{
string docText =
"<html><!DOCTYPE html>" + Environment.NewLine +
"<style type=\"text/css\"> #footer { position: absolute; bottom: 0; left: 0; height: 0px; } </style>" + Environment.NewLine +
"<script type=\"text/javascript\">" + Environment.NewLine +
"function appendHtml(o) {" + Environment.NewLine +
"var div = document.createElement(\"div\");" + Environment.NewLine +
"div.innerHTML = o;" + Environment.NewLine +
"document.body.appendChild(div);" + Environment.NewLine +
"}" + Environment.NewLine +
"</script>" + Environment.NewLine + "<body>" + Environment.NewLine + "</body></html>" +
//"<body></body>" +
//"<table align=\"center\" border=\"0px\" id=\"footer\" width=\"100%\"></table>" +
Environment.NewLine;
msgLog.DocumentText = docText;
Application.DoEvents();
HtmlTable table = new HtmlTable();
table.Width = "100%";
HtmlTableRow tr = new HtmlTableRow();
tr.Cells.Add(new HtmlTableCell("shit"));
tr.Cells[0].Width = "100%";
table.Rows.Add(tr);
InsertHtmlControl(table, msgLog);
}
public static void InsertHtmlControl(HtmlControl c, WebBrowser wb)
{
// create a HtmlTextWriter;
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter htmlw = new HtmlTextWriter(sw);
// render the control as html
c.RenderControl(htmlw);
////invoke the script passing in the html
//object[] p = new object[1];
//p[0] = (object)sb.ToString();
//Trace.WriteLine("Invoking: " + sb.ToString());
//wb.Document.InvokeScript("appendHtml", p);
HtmlElement body = wb.Document.GetElementsByTagName("body")[0];
body.InnerHtml = sb.ToString();
wb.Update();
htmlw.Close();
htmlw.Dispose();
sw.Dispose();
}