I am trying to copy data that is displayed in a asp listview.(I want to email it)
I can grab the information using javascript to grab the html but it is unstyled.
I don't want to have to go inside each control to save the data before each time it is outputted. Is their a better solution?
Html is html, if you keep your formatting in a css you will need to attach related css-classes and tags in the e-mails as well which should be quite simple.
I know this has been answered, but I thought I would add this too in case it helps. I use the following to return the HTML of a given control. As mentioned, you would just need to include any CSS in the HTML of the Email.
using System.Text;
using System.IO;
using System.Web.UI;
public string RenderControl(Control ctrl)
{
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);
ctrl.RenderControl(hw);
return sb.ToString();
}
Stolen from several blog sites like this one.
Related
I am trying to generate a Pdf from Html string using DynamicPdf.HmtlConverter library.
For generating Html string I am using HtmlTextWriter class from System.Web.UI.
I am trying to add the external style sheet as follows :
StringBuilder sb = new StringBuilder();
sb.Append(#"<!DOCTYPE html>" + Environment.NewLine);
StringWriter stringWriter = new StringWriter();
using (HtmlTextWriter writer = new HtmlTextWriter(stringWriter))
{ //adding head and link tag
writer.RenderBeginTag(HtmlTextWriterTag.Html);
writer.RenderBeginTag(HtmlTextWriterTag.Head);
writer.Write("<meta charset=" + "\"UTF-8\">");
//Add Link tag attributes
writer.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet");
writer.AddAttribute(HtmlTextWriterAttribute.Href,#"~\Stylesheet1.css"); //style sheet reference
writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/css");
writer.RenderBeginTag(HtmlTextWriterTag.Link);
writer.RenderEndTag(); // end of Link tag
writer.RenderEndTag(); // end of head tag
// Body tag
writer.RenderBeginTag(HtmlTextWriterTag.Body)
writer.RenderEndTag(); // end of Body tag
writer.RenderEndTag(); // end of Html tag
}
sb.Append(stringWriter);
So "sb" will have the Html string which will be passed to DynamicPdf library method to generate Pdf as below :
ceTe.DynamicPDF.HtmlConverter.Converter.Convert(sb.ToString(),#"~\output3.pdf", null, options);
External style sheet does not show any effect on Html controls.
any suggestions how to use external style sheet with HtmlTextWriter and DynamicPdf library to generate a Pdf ..!!!
The issue is with path used for stylesheet. HTML does not recognizes any special meaning for '~' character. See RFC3986 Section:2.3
In Linux, '~' has a special meaning and translates to the home directory but for HTML it is just another character. I would suggest you to use Path.GetFullPath("~") to get full path to home directory and then use that instead.
Update:
I was mostly concentrated on the HTML part but I noticed that the third parameter of ceTe.DynamicPDF.HtmlConverter.Converter.Convert() is set to null. It must be the base-path for all the file paths used in html string. See DynamicPDF Reference
So the code should look something like this:
ceTe.DynamicPDF.HtmlConverter.Converter.Convert(sb.ToString(),#"~\output3.pdf", new Uri(#"file://C:\Users\Z0042ADE\source\repos\HtmlTextWriterDemo\HtmlTextWriterDemo\"), options);
Then you may not need to use any path in HTML string. This can be just stylesheet name:
writer.AddAttribute(HtmlTextWriterAttribute.Href,#"Stylesheet1.css");
Hopefully this will fix the issue.
This worked for me :
You can specify external CSS in the HTML source and use it for conversion without any problem using DynamicPdf library . You can get the CSS from a website using the URL or if you are using HTML string as input to the conversion and want to use external CSS then you will need to specify the base path to pick the resources. Please refer to the documentation on HTML converter base tags at:
[1]: https://www.dynamicpdf.com/docs/dotnet/html-converter-base-urls
Please see the code example below :
Below HTML text uses external styles from a file placed in the folder which is specified in the BasePath Uri.
Uri basepath = new Uri(#"C:\Temp\Resource\sytlesheet.css");
ceTe.DynamicPDF.HtmlConverter.Converter.Convert(htmlText, #"C:\Temp\MyHTmlPDF.pdf", basepath);
I am working in asp.net with C# website. I want to convert a HTML DIV which contains various html elements like divs,label, tables and images with css styles(background color, cssClass etc) and I want its whole content to be converted into PDF using iTextSharp DLL but here I am facing a issue that css is not getting applied.Can any one help me by providing any example or code snippet.
Install 2 NuGet packages iTextSharp and itextsharp.xmlworker and use the following code:
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
byte[] pdf; // result will be here
var cssText = File.ReadAllText(MapPath("~/css/test.css"));
var html = File.ReadAllText(MapPath("~/css/test.html"));
using (var memoryStream = new MemoryStream())
{
var document = new Document(PageSize.A4, 50, 50, 60, 60);
var writer = PdfWriter.GetInstance(document, memoryStream);
document.Open();
using (var cssMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(cssText)))
{
using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(html)))
{
XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, htmlMemoryStream, cssMemoryStream);
}
}
document.Close();
pdf = memoryStream.ToArray();
}
Check out Pechkin, a C# wrapper for wkhtmltopdf.
Specifically at this point in time (considering a pending pull request) I'd check out this fork that addresses a couple of bugs (particularly helpful in IIS based on my experience).
If you don't go with the fork / get other stability issues you may want to look at having some kind of "render queue" (e.g. in a database) and have a background process (e.g. Windows service) periodically run over the queue and render then store the binary content somewhere (either in database as well, or on file system). This depends entirely on your use-case though.
Alternatively the similar solution #DaveDev has comment linked to.
Is there a way to save html content of an aspx page in the pageload part of the cs file and have it loaded again on postback?
Maybe using a streamreader to save it then have the streamreader write the content back in?
If so does anyone have any examples?
Do you mean something like this, capturing the generated HTML by overriding the Render method?
protected override void Render(HtmlTextWriter writer)
{
string pageSource;
// setup a TextWriter to capture the markup
using (var sw = new StringWriter())
using (var htw = new HtmlTextWriter(sw))
{
// render the markup into our surrogate TextWriter
base.Render(htw);
// get the captured markup
pageSource = sw.ToString();
}
// render the markup into the output stream
writer.Write(pageSource);
// now you can do what you like with the captured markup in pageSource
}
ASP.NET has an extensive caching mechanism which is meant to do what you describe
Something along these lines HtmlTextWriter to String - Am I overlooking something? can be done. I've done it with the Render() method of the page, not the RenderContents method. I can't for the life of me remember why I did that, though. It may have been for versions of ASP.net before they introduced the ability to cache most of a page, except for small pieces. Unless you really need to do this, use the built in caching functionality.
I want to create a HTML document and create table init using C#. I don't want to use ASP or any thing like that. I want to do this by using C# Windows Application.
The created document should not use MS Word or may not depend on any other app and save it to any folder (C:\) etc. It is totally independent of any other MS product and can run in any PC
Something like this :)
String exportdirectory = "c:";
StreamWriter sw;
sw = File.CreateText(exportDirectory + "filename.html");
sw.WriteLine("<table>");
sw.WriteLine("<tr>");
sw.WriteLine("<td>");
sw.WriteLine("contents of table!");
sw.WriteLine("</td>");
sw.WriteLine("</tr>");
sw.WriteLine("</table>");
sw.Close();
This is just creating a string ( maybe using a StringBuilder ) and appending data, then save it with a StreamWriter. If you want something more versatile, try to use some sort of stringtemplate, http://www.antlr.org/wiki/display/ST/StringTemplate+Documentation for example, this could allow you to isolate the "view" portion of your application allowing some sort of configuration to easily drive the output generation.
Well its not clear why you have such requirement or why are u mentioning MS Word... it doesn't make sense...
But what you want is your programme to Create a HTMl File.. (you dont even need ASP.NEt for that.. its for web server programming...)
My best guess is you want something to emit data in HTML format according to some user requirements.
For that..
Simply just create a file with HTML Extension and start Emitting HTML specific tags to it.
Few guys have already mentioned how to do that.
A quick and Dirty way would be somthing like this...
public void CreateFile()
{
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("<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n");
sb.Append("<head>\r\n");
sb.Append("<meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\" />\r\n");
sb.Append("<title>My HTMl Page</title>\r\n");
sb.Append("</head>\r\n");
sb.Append("<body>\r\n");
sb.Append("<table>\r\n");
//If you are emiting some data like a list of items
foreach (var item in Items)
{
sb.Append("<tr>\r\n");
sb.Append("<td>\r\n");
sb.Append(item.ToString());
sb.Append("</td>\r\n");
sb.Append("</tr>\r\n");
}
sb.Append("</table>\r\n");
sb.Append("</body>\r\n");
sb.Append("</html>\r\n");
System.IO.StreamWriter sr = new System.IO.StreamWriter("Your file path .html");
sr.Write(sb.ToString());
}
There is also a System.Web.UI.HTML32TextWriter class that is specially ment for this purpose but you didn't wanted anything from ASP, so...
Im trying to find a best practice to load usercontrols using Ajax.
My first approach where simply using an UpdatePanel and popuplating it with LoadControl() on ajax postbacks but this would rerender other loaded usercontrols in the same UpdatePanel. Also I cannot have a predefined set of UpdatePanels since the number of UserControls I need to load will vary.
Is there any best practice for this type of scenario?
If needed I could implement a framework or some type of custom controls if that would be a solution but I would love to do this with ASP.NET 3.5 and the AjaxControlToolkit if possible.
Probably dozens of high-brow reasons for not doing it this way, but simply initalizing a page, adding the usercontrol, then executing and dump the resulting HTML wherever it may behoove you, is (in my simpleminded view) so mind-numbingly fast & fun that I just have to mention it...
Skip the UpdatePanels, just use a Label, a plain old span, or how about an acronym...
Using JQuery on the client side:
$('#SomeContainer').Load("default.aspx?What=GimmeSomeSweetAjax");
ServerSide:
if(Request.QueryString["What"]==GimmeSomeSweetAjax)
{
Page page = new Page();
Control control = (Control)LoadControl("~/.../someUC.ascx");
StringWriter sw = new StringWriter();
page.Controls.Add(control);
Server.Execute(page, sw, false);
Response.Write(sw.ToString());
Response.Flush();
Response.Close();
}
Nothing else executes, and the page's lifecycle has a real Kevorkian moment ;-)
I'm not sure, but maybe this tutorial by Scott Guthrie could be useful.
Had to use this on order to get the properties work!
var page = new Page();
var sw = new StringWriter();
var control = (UserControl)page.LoadControl("~/.../someUC.ascx");
var type = control.GetType();
type.GetProperty("Prop1").SetValue(control, value, null);
page.Controls.Add(control);
context.Server.Execute(page, sw, false);
context.Response.ContentType = "text/html";
context.Response.Write(sw.ToString());
context.Response.Flush();
context.Response.Close();