I can't seem to find a good way to print .htm files in c# using .net 4.0, visual studio 2010 and windows forms. When i tried to print it directly, it printed the raw html data instead of printing the "page" itself.
The only way i know to print it, is to use a WebBrowser control. When i print the document, it doesn't print colors and the page isn't printed correctly. For example, the edges are not drawn and so on.
Code for Web Browser :
public void Print()
{
// Create a WebBrowser instance.
WebBrowser webBrowserForPrinting = new WebBrowser();
// Add an event handler that prints the document after it loads.
webBrowserForPrinting.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(PrintDocument);
// Set the Url property to load the document.
webBrowserForPrinting.Url = new Uri(Core.textLog);
}
private void PrintDocument(object sender, WebBrowserDocumentCompletedEventArgs e)
{
((WebBrowser)sender).ShowPrintDialog();
//// Print the document now that it is fully loaded.
//((WebBrowser)sender).Print();
//// Dispose the WebBrowser now that the task is complete.
((WebBrowser)sender).Dispose();
}
What can i do?
Thank you!
Printing web pages will forever be the bane of your existence. There just isn't a solution out there that prints HTML directly to your printer really, really well. And even if you do find a program that does it well, it's only a matter of time until you try to print a page with some unsupported formatting, in which case you're right back where you started.
What we do is print HTML to a pdf file with a program called wkhtmltopdf. Then we open it in Acrobat (which has excellent printing support) and print from there. I can't say enough good things about wkhtmltopdf. It's command line driven, and its super, super fast. Best of all, its free. It has a companion program called wkhtmltoimage that will print to most popular image formats, too (bmp, jpg, png, etc).
After downloading/installing the program, you can run a quick test by going to your command prompt, navigating to the install folder, and typing:
wkhtmltopdf "http://YouWebAddress.com" "C:/YourSaveLocation.pdf"
It also has a ton of command line switches that give you greater control over the outputs (headers, footers, page numbering, etc etc).
Ok, as i said, problem was that edge are not drawn and neither are the backgrounds.
Here is how i solved it.
Hashtable values = new Hashtable();
values.Add("margin_left", "0.1");
values.Add("margin_right", "0.1");
values.Add("margin_top", "0.1");
values.Add("margin_bottom", "0.1");
values.Add("Print_Background", "yes");
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Internet Explorer\PageSetup", true))
{
if (key == null) return;
foreach (DictionaryEntry item in values)
{
string value = (string)key.GetValue(item.Key.ToString());
if (value != item.Value.ToString())
{
key.SetValue(item.Key.ToString(), item.Value);
}
}
}
So before i print, i go to regedit, change the values, and the document gets printed perfectly. Hope this helps other people that have the same problem when printing from webbrowser control in windows forms.
Related
I have a C# WPF application (.NET 4.6) that needs to print a number of Page objects.
Each Page is setup in the XAML editor to be exactly 1 page of A4 in size and the content is build from a number of label, border and image components placed on the Page.
I added a method to my Page class that adds some dynamic data at run-time to the Page and then prints it using PrintVisual().
In fact: Its a loop that fills a Page object with the dynamic content and then calls PrintVisual() to print it. For each iteration, some new content is placed in the Page. (See sample code.)
// Print method of the Page object.
public void PrintIt(int totalpages)
{
PrintDialog pDialog = new PrintDialog();
// If not cancelled then print
if (pDialog.ShowDialog() == false) return; // User cancelled. Don't bother
for(int pagenum=1; i<=totalpages; i++)
{
// Omitted several dozen statements that fill/update the content of various
// label components based on the pagenumber.
this.UpdateLayout(); // Required to re-render new page properly before printing.
pDialog.PrintVisual(this, "My PrintJob");
}
}
This works well, expect for the fact that each PrintVisual() creates a separate print-job, which makes it impossible to print double-sided (and when printing to PDF each page ends up in a new file).
I need to tie all pages (PrintVisual() calls) in a single print-job. I'm fairly sure that I need to use a PrintDocument(), but I can't seem to figure out how to construct the required FlowDocument and populate it with my actual prints.
I'm quite new to WPF programming so I'm probably missing something obvious, but as far as I can't tell there isn't any simple way to do this.
Can anyone give me a push in the right direction ?
I have some trouble using the webbrowser control in C#, especially when I print it. The thing is, I have a Barcode in my html file and I have to print it (I use a font to create the code). When I open the html file with Firefox or any other Web browser, my barecode is good and I can scan it. But, when I open my file with my webbrowser in c#, or when I print it, the webbrowser ad 2 characters after the barecode. And, when I print the file, my document is not centered, it's like the webbrowser add a margin-left property. So my question is, is there any way to print an html file, using a webbroser, exactly how I see the html file when I use firefox or chrome for example. Here is the code I use.
curDir = Directory.GetCurrentDirectory();
webBrowserA4.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(PrintDocument);
webBrowserA4.Url = new Uri(String.Format("file:///{0}/print.html", curDir));
private void PrintDocument(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// Print the document now that it is fully loaded.
((WebBrowser)sender).Print();
// Dispose the WebBrowser now that the task is complete.
((WebBrowser)sender).Dispose();
}
EDIT: So, now, I have another problem, here is the screen of what my file looks like when I print it: http://imgur.com/q7ovEA1 As you can see, there is a "margin-left", and I can't remove it. I also want to remove this "page 1 of 1" and the Title.
I am trying to display HTML files (containing local images) in a WebBrowser control. User can select the file using an OpenFileDialog, after which it is displayed in the control.
But I have these problems I am struggling to solve:
Since I've added the control to my Form, it's been loading really slowly. It takes almost 10s for the form to instantiate.
WebBrowser.Navigate only works the first time. When I try to load the second file, nothing happens. I have tried calling Refresh, Update, OpenNew, opening about:blank between two files, but I just don't have a clue how to do it properly. Only the initially opened file remains shown, no exceptions or warnings ever pop up when I try to navigate to a different page.
Am I doing something wrong? For example, Lutz Roeder's Writer starts instantly and loads subsequent files without problems, but it uses lots of interop (and is editable), so I am trying to avoid all that stuff.
The way I have been loading local .html files into a WebBrowser is like so:
OpenFileDialog ofd = new OpenFileDialog();
// Do filtering here
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
webBrowser1.DocumentText = System.IO.File.ReadAllText(ofd.FileName);
}
It can load files one after another with no problems. If you are trying to load a big html file when the form is initializing or is opening this could explain the 10 second loading time. My form loaded almost instantly when it had a WebBrowser control on it.
Hope this helps!
Edit: Try setting the stream of the WebBrowser:
System.IO.Stream s = System.IO.File.OpenRead(ofd.FileName);
webBrowser1.DocumentStream = s;
i want to know how i can open a browser to a specific web page and then fill out some of the content of the boxes on that page.
My idea is for someone to be able to order a particular item from our internal ordering system. The barcodes for these items are what will populate the fields on the page i want to open.
I no i can open a new instance of ie using Process.Start("IEXPLORE.EXE", url); howver how do i get a handle on that exact ie instance window so i can begin to add the required data to the fields?
Is this even possible?
Thanks very much
WatiN should help with this. I've generally used it for acceptance testing of web apps, but the principle is the same. Open a browser instance, reference stuff in the DOM, manipulate form elements, etc.
In addition to WatiN (as was suggested in another answer), you might consider a load testing package like Web Performance Load Tester. They have a free version that lets you run up to 10 virtual users at a time, which will perform scripted actions.
Another option would be to use a standard WebBrowser object to load your website. The WebBrowser object allows you to access and alter certain web parts. Below is sample code that automatically searches Bing:
private void LoadPage()
{
WebBrowser webBrowser1 = new WebBrowser();
webBrowser1.Navigate("http://www.bing.com");
//Wait for document to load...
while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
//Set the text of the search input
HtmlElement txtTextField = webBrowser1.Document.GetElementById("sb_form_q");
txtTextField.InnerText = "My test text";
//Perform a click on the search button
HtmlElement btnSubmit = webBrowser1.Document.GetElementById("sb_form_go");
btnSubmit.InvokeMember("click");
}
HiI am using C# WPF webbrowser control to show html file in my local machine, I added a print feature to my application by executing print command of webbrowser control, but default behavior of Internet Explorer is to print file url in the bottom of the screen , can I turn header and footer printing for my control? Have WebBrowser control ability to print preview? Sometimes printed page is cut, can someone help to understand what is the problem. Thanks a lot!!!
I did it once (sorry, I don't have the application code now), and I did it playing with the register: check this MS article.
I advice you to store somewhere the current values of the keys and restore them after you're done printing.
EDIT
string keyName = #"Software\Microsoft\Internet Explorer\PageSetup";
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(keyName, true)) {
if (key != null) {
string old_footer = key.GetValue("footer");
string old_header = key.GetValue("header");
key.SetValue("footer", "");
key.SetValue("header", "");
Print();
key.SetValue("footer", old_footer);
key.SetValue("header", old_header);
}
}
About pages being cut
I'm not sure if I understood correctly what the problem is... in the application I was talking about before, I had the problem of tables being cut in half, so I played with CSS break after property (see also break before) to force page breaks, specifying special styles for the printer media. Hope this helps...