I'm looking for a simple way to print DIN-A4 paper with data from a database on it. The data should be filled into multiple tables with borders. Some of the data should have a different text format p.e. bold or underlined. I should also be able to print multiple images onto that sheet.
The program should be a Windows Forms Application or a console application written in C#.
Which is the easiest / most common way to format data and print it like that?
Any suggestions apreciated :)
EDIT:
this is my current code with almost no success. It actually prints but what I get is simply the xml file printed.
private void printButton_Click(object sender, EventArgs e)
{
string printPath = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
fileToPrint = new System.IO.StreamReader(printPath + #"\test.xml");
printFont = new System.Drawing.Font("Arial", 10);
PrintDocument printDocument1 = new PrintDocument();
printDocument1.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
printDocument1.Print();
fileToPrint.Close();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
float yPos = 0f;
int count = 0;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
string line = null;
float linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics);
while (count < linesPerPage)
{
line = fileToPrint.ReadLine();
if (line == null)
{
break;
}
yPos = topMargin + count * printFont.GetHeight(e.Graphics);
e.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin, yPos, new StringFormat());
count++;
}
if (line != null)
{
e.HasMorePages = true;
}
}
Printing in .NET is quite hard without additional tools.
Visual Studio 2008 and Report Wizard
Its my favorite tool. It's based on Microsoft Reporting Services which is available in Visual Studio 2008. It works similar to MS Access reports functionality.
Unfortunatelly i was not able to run it and design reports in other Visual Studio versions. Reporting Services are available in .NET Framework and you can use them with any Visual Studio, but there is no Report Designer/Wizard tool in versions other than 2008).
Crystal Reports (expensive but really good).
If you have some time you may fight with pixels like this:
Simplified .NET printing in C# Dave Brighton at codeproject.com
WebBrowser control, as #colosso wrote in another answer, but this depends on Internet Explorer version and i personally don't like this method.
I found two possibilities:
1) In my opinion this is the worse one. I found a third-party software called "Antena house formatter". You can find it on www.antennahouse.com but it's unfortunately neither open source nor free software. This software allows you to convert xml, xsl or xsl-fo data into pdf and other formats. From there you could print it with standard c#.
I didn't chose this way for some reasons: To be hooked on a third-party software is no good solution in my opinion, although this Antennahouse formatter is a quite nice, reliable and fast software.
2) This is the solution I have chosen. You can create a simple WebBrowser control and fill it either with a saved html file or you can just fill it with a dynamically created string. I now generate a string witch contains the whole html document an load it into the Webbrowser control:
webBrowser1.Document.OpenNew(true);
string strHtml = "<html><head></head><body></body></html>";
webBrowser1.Document.Write(strHtml);
When loading the form I open a new "tab" with:
webBrowser1.Navigate("about:blank");
You can either show the Webbrowser control to have a "preview" of the site that is getting printed or just hide it. Finally, when you loaded you html file into the control you can print it with:
webBrowser1.Print();
It will ow print the document with you default printer. I know, using a html file to print a site like that feels some sort of "hacky" but it's the easiest way I found to do something like that. Especially if you net to print very complex Sites with many different things on it.
Nice to know:
I had to print DIN-A4 sites. I set my content with to 670px and that fits nice.
You are printing with a Webbrowser control. He will take the printer settings from your local installed Internet Explorer (or the registry if we want to be exactly). If you want to change it go into your IE > Printing > Page settings... and set you desired options or just change it in your registry.
Hope this helps someone :)
Related
This is a WPF desktop app related to ID Card printing. One of the new features we're trying to add is magstripe encoding. After having spent several days, I'm still not sure where to start. New questions keep popping up the more I google. I'll summarize them here. I'll be glad to hear from experts (even if someone can answer one/some of the questions):
Do magstripe printers work as normal printers too (means can they print text and graphics too, or is that we print the cards on other, regular printers in the first pass and then insert them into magstripe printer for encoding magnetic data onto them, in the 2nd pass)?
If answer to Q1 is yes, how do I send magstripe data to the printer during regular printing job (done through WPF, using PrintDialog, FixedDocument etc).
I downloaded and examined Zebra printers SDK. It looks like these printers DO support text/graphics printing in addition to magstripe encoding, but their SDK requires me to call their native printing functions, which doesn't fit in WPF's standard printing model. How to overcome this?
In another place I read that magstripe printers require simple ASCII text in specific format to get them encoded onto the card, and that I can do this even from Notepad. If this is true, the answer to Q1 might be negative. But then again, how does this method work in conjunction with regular WPF printing?
Edit
I also learnt that there are magstripe fonts that when placed in a document, end up being encoded to the magnetic stripe instead of regular printing. If this is true, it would very nicely fit in WPF printing model. But googling hasn't returned too many promising results for magstripe fonts. Maybe this is a brand-specific feature.
I am currently working on a similar WPF project that requires magnetic encoding as well as image printing on ID cards. I have found that magnetic encoding is very simple as long as the drivers for the printer with magnetic coding are installed on the host. One vital piece to watch out for is the delimiter being used by the driver. This could be NULL, ZERO, or Space. This comes into play when encoding a specific track (i.e. Track 2 but not Track 1 as we are). I use the NULL setting which allows only the Track 2 data to be sent in the job. This setting is found in the Printer Preferences for the Fargo printers (Control Panel -> Hardware and Sound -> Devices and Printers -> Right-Click Printer -> Printer Preferences). Here is an example of these Preferences (note the ASCII Offset field):
I do not believe that you MUST use the SDK for the printer you are using. I am using a Fargo printer but wrote my own Print functionality using PrintDocument and PrintPage for both magnetic encoding and images.
An example and quick test is to send Track 2 data to the printer using Notepad++ (or similar). Copy and paste this into the first line of the editor and print (using the card printer).
~2;000099990000?
The driver should pick up the fact that it is Track data and handle it accordingly without any more input from you. You may need to play with the printer preferences as stated.
The ~2; denotes Track 2 followed by a 12-character data string followed by the end sentinel (?). There is plenty of documentation pertaining to Track data and layouts online. This is assuming a NULL delimiter value (between Track 1 and Track 2).
Printing on both sides of the card can be cumbersome, but that does not appear to be within the scope of this question. I recommend using Windows native PrintDocument and PrintPage methods within your WPF application; the SDK you have downloaded is likely using these methods in the background, anyhow.
An example of PrintDocument/PrintPage:
private int PageCount { get; set; }
public void Print()
{
PageCount = 0;
PrintDocument pd = new PrintDocument
{
// Define your settings
PrinterSettings = {
Duplex = Duplex.Horizontal,
PrinterName = ConfigurationManager.AppSettings["PrinterName"]
}
};
Margins margins = new Margins(0, 0, 0, 0);
pd.OriginAtMargins = true;
pd.DefaultPageSettings.Margins = margins;
pd.PrintPage += new PrintPageEventHandler(this.PrintPage);
PrintPreviewDialog ppd = new PrintPreviewDialog();
ppd.Document = pd;
// Uncomment to show a Print Dialog box
//if (ppd.ShowDialog() == DialogResult.OK)
pd.Print();
pd.Dispose();
}
private void PrintPage(object o, PrintPageEventArgs e)
{
PrintDocument p = (PrintDocument)o;
p.DefaultPageSettings.Landscape = true;
p.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
p.DefaultPageSettings.PaperSize = new PaperSize("YourPaperSizeName", 340, 215);
p.OriginAtMargins = true;
o = p;
e.PageSettings.PrinterSettings.DefaultPageSettings.Landscape = true;
e.PageSettings.Landscape = true;
// Do Print First Side (MAG ENCODE)
if (PageCount == 0)
{
// Do Side 1 Stuff
// If Two-Sided Printing: true
e.HasMorePages = true;
//If no more, set above to false and PageCount = 0, else...
PageCount++;
}
else
{
// Do Print on Other Side
// STUFF
// STUFF
// Since only two sides/card printing: false
e.HasMorePages = false;
PageCount = 0;
}
}
Again, magnetic encoding should not be brand-specific and you should not have to rely solely on their SDK to perform print jobs.
I hope this helps!
I have a project where I create sample documents. Code here :
private void btnExcel_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (AutomationFactory.IsAvailable)
{
dynamic excel = AutomationFactory.CreateObject("Excel.Application");
excel.Visible = true;
dynamic workbook = excel.workbooks;
workbook.Add();
dynamic sheet = excel.ActiveSheet;
dynamic cell = null;
int i;
int z = 20;
for (i = 1; i <= 20; i++)
{
cell = sheet.Cells[i, 1];
cell.Value = i.ToString();
cell = sheet.Cells[i, 2];
cell.Value = z.ToString();
z--;
}
}
}
As you can see, this is for Excel documents. Is there any way I can something like this and export in to PDF files? Thanks for the insights.
Yes you can.
You can call a WCF service operation passing it all the data that it needs. Then do all what is required to generate the PDF file. After you've done that, you have two options:
You can send back the bytes as the result of the operation. In this case, you can show the user a SaveDialog to save the file to his local disk.
You can send the generated file to another aspx page and display the PDF file to the user who then has the choice to save it to his local disk or simply view it.
I hope that was what you're looking for.
Sure, you can. But why?! As I understand with AutomationFactory.CreateObject you can do it when on client machine Excel or PDF are installed.
But dealing with web application (especially when it's not an enterprise applications) you want to see pdf/xls/xlsx/... anywhere and you can relay on what is installed on client machine or not.
I have similar situation for one of my projects. We are using XPS format to show in silverlight because it has native support. And other formats are converted to xps.
There nuances in conversion, e.g. for excel documents I think best way is to convert each sheet separately, and implement special kind viewer that differs from viewer, for example, for word documents or pdf's.
There are 3rd party viewers that allow to view not only xps on silverlight but pdf too. But without them you can only let user to download PDF file not to view that, because these 3rd part viewer most likely convert pdf to xps under the hood.
Any way, especially without 3rd parties, it will take huge efforts to implement PDF viewer on silverlight. So I suggest you to use xps for viewing. But when you need to have pdf files for downloads than use XPS for viewing and PDF on download. In such case your converters will produce 2 formats for each sitation.
For example, look at
http://firstfloorsoftware.com/blog/announcement-document-toolkit-for-silverlight/
http://silverpdf.codeplex.com/
http://www.componentone.com/SuperProducts/PdfViewerSilverlight/
We have a .NET app which prints to both real printers and PDF, currently using PDFsharp, although that part can be changed if there's a better option. Most of the output is generated text or images, but there can be one or more pages that get appended to the end. That page(s) are provided by the end-user in PDF format.
When printing to paper, our users use pre-printed paper, but in the case of an exported PDF, we concatenate those pages to the end, since they're already in PDF format.
We want to be able to embed those PDFs directly into the print stream so they don't need pre-printed paper. However, there aren't really any good options for rendering a PDF to a GDI page (System.Drawing.Graphics).
Is there a vector format the PDF could be converted to by some external program, that could rendered to a GDI+ page without being degraded by conversion to a bitmap first?
In an article titled "How To Convert PDF to EMF In .NET," I have shown how to do this using our PDFOne .NET product. EMFs are vector graphics and you can render them on the printer canvas.
A simpler alternative for you is PDF overlay explained in another article titled "PDF Overlay - Stitching PDF Pages Together in .NET." PDFOne allows x-y offsets in overlays that allows you stitch pages on the edges. In the article cited here, I have overlaid the pages one over another by setting the offsets to zero. You will have set it to page width and height.
DISCLAIMER: I work for Gnostice.
Ghostscript can output PostScript (which is a vector file) which can be directly sent to some types of printers. For example, if you're using an LPR capable printer, the PS file can be directly set to that printer using something like this project: http://www.codeproject.com/KB/printing/lpr.aspx
There are also some commercial options which can print a PDF (although I'm not sure if the internal mechanism is vector or bitmap based), for example http://www.tallcomponents.com/pdfcontrols2-features.aspx or http://www.tallcomponents.com/pdfrasterizer3.aspx
I finally figured out that there is an option that addresses my general requirement of embedding a vector format into a print job, but it doesn't work with GDI based printing.
The XPS file format created by Microsoft XPS Writer print driver can be printed from WPF, using the ReachFramework.dll included in .NET. By using WPF for printing instead of GDI, it's possible to embed an XPS document page into a larger print document.
The downside is, WPF printing works quite a bit different, so all the support code that directly uses stuff in the Sytem.Drawing namespace has to be re-written.
Here's the basic outline of how to embed the XPS document:
Open the document:
XpsDocument xpsDoc = new XpsDocument(filename, System.IO.FileAccess.Read);
var document = xpsDoc.GetFixedDocumentSequence().DocumentPaginator;
// pass the document into a custom DocumentPaginator that will decide
// what order to print the pages:
var mypaginator = new myDocumentPaginator(new DocumentPaginator[] { document });
// pass the paginator into PrintDialog.PrintDocument() to do the actual printing:
new PrintDialog().PrintDocument(mypaginator, "printjobname");
Then create a descendant of DocumentPaginator, that will do your actual printing. Override the abstract methods, in particular the GetPage should return DocumentPages in the correct order. Here's my proof of concept code that demonstrates how to append custom content to a list of Xps documents:
public override DocumentPage GetPage(int pageNumber)
{
for (int i = 0; i < children.Count; i++)
{
if (pageNumber >= pageCounts[i])
pageNumber -= pageCounts[i];
else
return FixFixedPage(children[i].GetPage(pageNumber));
}
if (pageNumber < PageCount)
{
DrawingVisual dv = new DrawingVisual();
var dc = dv.Drawing.Append();
dc = dv.RenderOpen();
DoRender(pageNumber, dc); // some method to render stuff to the DrawingContext
dc.Close();
return new DocumentPage(dv);
}
return null;
}
When trying to print to another XPS document, it gives an exception "FixedPage cannot contain another FixedPage", and a post by H.Alipourian demonstrates how to fix it: http://social.msdn.microsoft.com/Forums/da/wpf/thread/841e804b-9130-4476-8709-0d2854c11582
private DocumentPage FixFixedPage(DocumentPage page)
{
if (!(page.Visual is FixedPage))
return page;
// Create a new ContainerVisual as a new parent for page children
var cv = new ContainerVisual();
foreach (var child in ((FixedPage)page.Visual).Children)
{
// Make a shallow clone of the child using reflection
var childClone = (UIElement)child.GetType().GetMethod(
"MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic
).Invoke(child, null);
// Setting the parent of the cloned child to the created ContainerVisual
// by using Reflection.
// WARNING: If we use Add and Remove methods on the FixedPage.Children,
// for some reason it will throw an exception concerning event handlers
// after the printing job has finished.
var parentField = childClone.GetType().GetField(
"_parent", BindingFlags.Instance | BindingFlags.NonPublic);
if (parentField != null)
{
parentField.SetValue(childClone, null);
cv.Children.Add(childClone);
}
}
return new DocumentPage(cv, page.Size, page.BleedBox, page.ContentBox);
}
Sorry that it's not exactly compiling code, I just wanted to provide an overview of the pieces of code necessary to make it work to give other people a head start on all the disparate pieces that need to come together to make it work. Trying to create a more generalized solution would be much more complex than the scope of this answer.
While not open source and not .NET native (Delphi based I believe, but offers a precompiled .NET library), Quick PDF can render a PDF to an EMF file which you could load into your Graphics object.
Anyone knows how to load a .AI file (Adobe Illustrator) and then rasterize/render the vectors into a Bitmap so I could generate eg. a JPG or PNG from it?
I would like to produce thumbnails + render the big version with transparent background in PNG if possible.
Ofcause its "possible" if you know the specs of the .AI, but has anyone any knowledge or code to share for a start? or perhaps just a link to some components?
C# .NET please :o)
Code is most interesting as I know nothing about reading vector points and drawing splines.
Well, if Gregory is right that ai files are pdf-compatible, and you are okay with using GPL code, there is a project called GhostscriptSharp on github that is a .NET interface to the Ghostscript engine that can render PDF.
With the newer AI versions, you should be able to convert from PDF to image. There are plenty of libraries that do this that are cheap, so I would choose buy over build on this one. If you need to convert the older AI files, all bets are off. I am not sure what format they were in.
private void btnGetAIThumb_Click(object sender, EventArgs e)
{
Illustrator.Application app = new Illustrator.Application();
Illustrator.Document doc = app.Open(#"F:/AI_Prog/2009Calendar.ai", Illustrator.AiDocumentColorSpace.aiDocumentRGBColor, null);
doc.Export(#"F:/AI_Prog/2009Calendar.png",Illustrator.AiExportType.aiPNG24, null);
doc.Close(Illustrator.AiSaveOptions.aiDoNotSaveChanges);
doc = null; //
}
Illustrator.AiExportType.aiPNG24 can be set as JPEG,GIF,Flash,SVG and Photoshop format.
I Have Tested that with Pdf2Png and it worked fine with both .PDF and .ai files.
But I don't know how it will work with transparents.
string pdf_filename = #"C:\test.ai";
//string pdf_filename = #"C:\test.pdf";
string png_filename = "converted.png";
List<string> errors = cs_pdf_to_image.Pdf2Image.Convert(pdf_filename, png_filename);
I want to print HTML from a C# web service. The web browser control is overkill, and does not function well in a service environment, nor does it function well on a system with very tight security constraints. Is there any sort of free .NET library that will support the printing of a basic HTML page? Here is the code I have so far, which does not run properly.
public void PrintThing(string document)
{
if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
{
Thread thread =
new Thread((ThreadStart) delegate { PrintDocument(document); });
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
else
{
PrintDocument(document);
}
}
protected void PrintDocument(string document)
{
WebBrowser browser = new WebBrowser();
browser.DocumentText = document;
while (browser.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
browser.Print();
}
This works fine when called from UI-type threads, but nothing happens when called from a service-type thread. Changing Print() to ShowPrintPreviewDialog() yields the following IE script error:
Error: dialogArguments.___IE_PrintType is null or not an object.
URL: res://ieframe.dll/preview.dlg
And a small empty print preview dialog appears.
You can print from the command line using the following:
rundll32.exe
%WINDIR%\System32\mshtml.dll,PrintHTML
"%1"
Where %1 is the file path of the HTML file to be printed.
If you don't need to print from memory (or can afford to write to the disk in a temp file) you can use:
using (Process printProcess = new Process())
{
string systemPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
printProcess.StartInfo.FileName = systemPath + #"\rundll32.exe";
printProcess.StartInfo.Arguments = systemPath + #"\mshtml.dll,PrintHTML """ + fileToPrint + #"""";
printProcess.Start();
}
N.B. This only works on Windows 2000 and above I think.
I know that Visual Studio itself (at least in 2003 version) references the IE dll directly to render the "Design View".
It may be worth looking into that.
Otherwise, I can't think of anything beyond the Web Browser control.
Easy! Split your problem into two simpler parts:
render the HTML to PDF
print the PDF (SumatraPDF)
-print-to-default $file.pdf prints a PDF file on a default printer
-print-to $printer_name $file.pdf prints a PDF on a given printer
If you've got it in the budget (~$3000), check out PrinceXML.
It will render HTML into a PDF, functions well in a service environment, and supports advanced features such as not breaking a page in the middle of a table cell (which a lot of browsers don't currently support).
I tool that works very well for me is HiQPdf. https://www.hiqpdf.com/
The price is reasonable (starts at $245) and it can render HTML to a PDF and also manage the printing of the PDF files directly.
Maybe this will help. http://www.codeproject.com/KB/printing/printhml.aspx
Also not sure what thread you are trying to access the browser control from, but it needs to be STA
Note - The project referred to in the link does allow you to navigate to a page and perform a print without showing the print dialog.
I don't know the specific tools, but there are some utilities that record / replay clicks. In other words, you could automate the "click" on the print dialog. (I know this is a hack, but when all else fails...)