Send output from SSRS as PDF direct to printer - c#

I am trying to get the out put from SSRS export and send it direct to a Server side printer without calling a print Dialog
ReportingService.ReportExporter.Export("basicHttpEndpoint", new NetworkCredential("userNmae", "*********"), reportName, parameters.ToArray(), reportFormat, out output, out extension, out mimeType, out encoding, out warnings, out streamIds);
In this case the export type is an Image; I am trying to get the output (which is a Byte Array) and setting a Memory stream and then trying to print directly using PrintDocumen() as follows
Stream stream = new MemoryStream(output);
StreamReader streamToPrint = new StreamReader(stream);
var pd = new PrintDocument();
pd.PrintPage += pd_PrintPage;
pd.PrintController = new StandardPrintController();
pd.Print();
The pd_PrintPage is well documented onthe web and MSDN
private void pd_PrintPage(object sender, PrintPageEventArgs ev)
{
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = ev.MarginBounds.Left;
float topMargin = ev.MarginBounds.Top;
string line = null;
// Calculate the number of lines per page.
linesPerPage = ev.MarginBounds.Height /
printFont.GetHeight(ev.Graphics);
// Print each line of the file.
while (count < linesPerPage &&
((line = streamToPrint.ReadLine()) != null))
{
yPos = topMargin + (count *
printFont.GetHeight(ev.Graphics));
ev.Graphics.DrawString(line, printFont, Brushes.Black,
leftMargin, yPos, new StringFormat());
count++;
}
// If more lines exist, print another page.
if (line != null)
ev.HasMorePages = true;
else
ev.HasMorePages = false;
}
I am not able to get the format of the data, it just prints the image data as characters. DO I need to convert the output data to another format?

Becasue you're telling the print command to brint the bytes as text instead of rendering the output. In order to render the stream to the printer you need a PDF print driver (e.g. Acrobat). Here are some options:
https://stackoverflow.com/questions/8338953/print-in-memory-pdf-without-saving-directly-without-a-printer-dialog-or-user-i
Printing a PDF in c# using a stream ... can it be done ?

Related

How to print a text file using PrintDialog in C#

I am new to C# windows forms.
I am trying to print the content of a Text file using the PrintDialog as shown in screenshot.
Screenshot
The following code is working correctly and it is printing but the printing process occurs immediately without opening the PrintDialog. I want to open the PrintDialog because I have 3 printers and I want to select a specific printer and when I click OK I want to print it.
Anyone knows how to modify this code so it can display the PrintDialog box so I can select a printer and continue printing?.
private void Print_Click(object sender, EventArgs e)
{
string filename = #"D:\\File1.txt";
//Create a StreamReader object
reader = new StreamReader(filename);
//Create a Verdana font with size 10
verdana10Font = new Font("Verdana", 10);
//Create a PrintDocument object
PrintDocument pd = new PrintDocument();
//Add PrintPage event handler
pd.PrintPage += new PrintPageEventHandler(this.PrintTextFileHandler);
//Call Print Method
pd.Print();
//Close the reader
if (reader != null)
reader.Close();
}
private void PrintTextFileHandler(object sender, PrintPageEventArgs ppeArgs)
{
//Get the Graphics object
Graphics g = ppeArgs.Graphics;
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = 0;
float topMargin = 50;
string line = null;
//Calculate the lines per page on the basis of the height of the page and the height of the font
linesPerPage = ppeArgs.MarginBounds.Height / verdana10Font.GetHeight(g);
//Now read lines one by one, using StreamReader
while (count < linesPerPage && ((line = reader.ReadLine()) != null))
{
//Calculate the starting position
yPos = topMargin + (count * verdana10Font.GetHeight(g));
//Draw text
g.DrawString(line, verdana10Font, Brushes.Black, leftMargin, yPos, new StringFormat());
//Move to next line
count++;
}
//If PrintPageEventArgs has more pages to print
if (line != null)
{
ppeArgs.HasMorePages = true;
}
else
{
ppeArgs.HasMorePages = false;
}
}
You can do so using PrintDialog.
PrintDialog pdialog = new PrintDialog();
pdialog.Document = pd;
if (pdialog.ShowDialog() == DialogResult.OK)
{
pd.Print();
}
Complete Code
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(this.PrintTextFileHandler);
PrintDialog pdialog = new PrintDialog();
pdialog.Document = pd;
if (pdialog.ShowDialog() == DialogResult.OK)
{
pd.Print();
}

C# System.Drawing - DrawString method - arabic string issue

I have the following issue when trying to draw a string and then printing it to PDF by Amyuni Printer :
where I couldn't select the text when pressing (Ctrl+A) , I need this PDF file to use it into another PDF reader , and it seems that the reader , tries to read the selected area not the actual text area .
I'm using the following code to do this stuff :
Font printFont = new Font("Simplified Arabic Fixed", (float)11, FontStyle.Regular);
StreamReader Printfile;
using (StreamReader Printfile = new StreamReader(#"C:\20_2.txt", Encoding.Default))
{
try
{
PrintDocument docToPrint = new PrintDocument();
PaperSize ps = new PaperSize("A4", 827, 1169);
bool bolFirstPage = true;
docToPrint.DefaultPageSettings.PaperSize = ps;
docToPrint.DefaultPageSettings.Landscape = true;
docToPrint.DocumentName = "docName" + DateTime.Now.Ticks.ToString(); //Name that appears in the printer queue
string FirstLine = Printfile.ReadLine();
bool bIsArabic = true;
docToPrint.PrintPage += (s, ev) =>
{
float nFontHight = printFont.GetHeight(ev.Graphics);
bIsArabic = true;
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = 1008;
float topMargin = 120;
string line = null;
//Calculate the number of lines per page.
linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics) + 2;
Image img = Image.FromFile(#"C:\image.bmp");
ev.Graphics.DrawImage(img, 6, 1, 1095, 728);
//***Image Reslution is Working good -->***
StringFormat format = new StringFormat()/*arabic*/;
line = Printfile.ReadLine();
format = new StringFormat(StringFormatFlags.DisplayFormatControl | StringFormatFlags.DirectionRightToLeft)/*arabic*/;
do
{
yPos = topMargin + ((count) * printFont.GetHeight(ev.Graphics) * (float)0.91);
line = " تجربة تجربة تجربة تجربة تجربة";
ev.Graphics.DrawString(line, printFont, Brushes.DeepPink, leftMargin, yPos, format);
count++;
} while ((line = Printfile.ReadLine()) != null && !line.Contains(''));// lines contains \0 as UniCode
// If more lines exist, print another page.
if (line != null)
ev.HasMorePages = true;
else
ev.HasMorePages = false;
};
docToPrint.Print();
}
catch (System.Exception f)
{
MessageBox.Show(f.Message);
}
}
}
when I'm using another font type like "Arial" I can select near to 90% of the text, but unfortunately I have to use only the font type "Simplified Arabic Fixed" , and I'm using windows server 2003.
one more thing , when i try to print directly Arabic text from notepad it's work fine.

Programmatically provide a filepath as input file for “Microsoft Print to PDF” printer

Desired result
I want to print a file to a new PDF using the Windows 10 printer "Microsoft Print to PDF" which is installed by default.
When you select this printer as your default printer and use your context menu on a file and select Print, it only asks for a save directory and name. After that, it immediately converts to PDF and saves the file.
As long as MS Office is installed, this works for Word, Excel, PowerPoint file types. But also for common image types and normal text files.
I'd like to automate this by providing a default path.
What I already tried
Stackoverflow already has this related question, but it does not address my specific problem and is rather incomplete and not working.
But I came up with this C# console program which uses the PDF printer to produce a new PDF on my desktop with "Hello World" as string
namespace PrintToPdf_Win10
{
using System;
using System.Drawing;
using System.Drawing.Printing;
class Program
{
public static void Main(string[] args)
{
PrintDocument printDoc = new PrintDocument
{
PrinterSettings = new PrinterSettings
{
PrinterName = "Microsoft Print to PDF",
PrintToFile = true,
PrintFileName = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/test.pdf"
}
};
printDoc.PrintPage += printDoc_PrintPage;
printDoc.Print();
Console.ReadKey(true);
}
static void printDoc_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawString("Hello World", new Font("Arial", 12), Brushes.Black, 50, 50);
}
}
}
Problem
How do I set the content of - let's say a Word file - as input for my printDoc object?
Is there a generic way to set printDoc by providing only a filePath to my file I want to print from? Or do I have to create a custom function for each possible filetype families like:
Office filetypes (doc, docx, xls, xlsx, xlsm, ppt, pptx etc.)
Image filetypes (png, bmp, jpg)
text files (txt, rtf, ini)
Here is simple solution how to print image or text (it could help you with formats like png, bmp, jpg, txt, ini)
private static StreamReader streamToPrint;
static void Main(string[] args)
{
string printFormat;
printFormat = "txt";
try
{
streamToPrint = new StreamReader(#"D:\TestText.txt");
PrintDocument printDoc = new PrintDocument
{
PrinterSettings = new PrinterSettings
{
PrinterName = "Microsoft Print to PDF",
PrintToFile = true,
PrintFileName = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/test.pdf"
}
};
printDoc.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize("A4", 210, 290);
printDoc.PrinterSettings.DefaultPageSettings.Landscape = false;
printDoc.PrinterSettings.DefaultPageSettings.Margins.Top = 0;
printDoc.PrinterSettings.DefaultPageSettings.Margins.Left = 0;
switch (printFormat)
{
case "jpg":
printDoc.PrintPage += printDoc_PrintImage;
break;
case "txt":
printDoc.PrintPage += printDoc_PrintText;
break;
default:
break;
}
printDoc.Print();
}
finally
{
streamToPrint.Close();
}
Console.ReadKey(true);
}
static void printDoc_PrintImage(object sender, PrintPageEventArgs e)
{
Image photo = Image.FromFile(#"D:\TestImage.jpg");
Point pPoint = new Point(0, 0);
e.Graphics.DrawImage(photo, pPoint);
}
static void printDoc_PrintText(object sender, PrintPageEventArgs e)
{
Font printFont;
printFont = new Font("Arial", 10);
float linesPerPage = 0;
// Calculate the number of lines per page.
linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics);
float yPos = 0;
int count = 0;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
string line = null;
while (count < linesPerPage &&
((line = streamToPrint.ReadLine()) != null))
{
yPos = topMargin + (count *
printFont.GetHeight(e.Graphics));
e.Graphics.DrawString(line, printFont, Brushes.Black,
leftMargin, yPos, new StringFormat());
count++;
}
// If more lines exist, print another page.
if (line != null)
e.HasMorePages = true;
else
e.HasMorePages = false;
}
As you know docx, xlsx are like zip files and you can unzip and get content as xml. So, it's much work to to if you want to print them

Printing a reciept on Dot matrix printer with custom paging from C#, asp.net

Have been looking for this from past 2days couldn't sort out, finally im here.
Now starting with the Question,
How to Print a reciept on dot matrix printer and stop after printing one reciept with out continuing to prnt complete page with white spaces from C#, iam able to print using the below JScript code, but continues to print whole page even after reciept is completed.
function Print-content() {
var DocumentContainer = document.getElementById('div2');
var WindowObject = window.open('', "PanelDetails"
,"width=1000,height=550,top=100
,left=150,toolbars=no,scrollbars=yes
,status=no,resizable=no");
WindowObject.document.writeln(DocumentContainer.innerHTML);
WindowObject.document.close();
WindowObject.focus();
WindowObject.open();
WindowObject.print();
}
But after printing half page, printer doesnt stop it proceeds and prints complete page with white spaces, well thats a usual problem seen on many sites but didn't come up with a solution, So have shifted to server side coding, using ITextSharp Dll.
Can some one please help me with complete solution for printing a reciept half Page and stop the printer after printing last line of the page, which is vertical half of the Letter Fanfold 8-1/2'' 11'' size.
for more clarity if required i will post C# code aswell, but in order not to mess i ignored the code
Thanks in advance
Here's my C# code
StringReader sr;
private void ExportDataListToPDF()
{
using (PrintDocument doc = new PrintDocument())
{
StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
this.div2.RenderControl(hw);
sr = new StringReader(sw.ToString());
doc.DocumentName = "Hello";
doc.DefaultPageSettings.Landscape = false;
PaperSize psize = new PaperSize("MyCustomSize", 216, 279);
doc.DefaultPageSettings.PaperSize = psize;
doc.PrinterSettings.DefaultPageSettings.PaperSize = psize;
psize.RawKind = (int)PaperKind.Custom;
doc.PrinterSettings.DefaultPageSettings.PaperSize.Height = doc.PrinterSettings.DefaultPageSettings.PaperSize.Height / 2;
doc.PrintPage += new PrintPageEventHandler(doc_PrintPage);
doc.PrinterSettings.PrinterName = "EPSON LQ-1150II";
doc.PrintController = new StandardPrintController();
// doc.PrinterSettings.PrintFileName = sw.ToString();
doc.Print();
}
}
public void doc_PrintPage(object sender, PrintPageEventArgs ev)
{
System.Drawing.Font printFont = new System.Drawing.Font(FontFamily.GenericSerif, 12);
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = ev.MarginBounds.Left;
float topMargin = ev.MarginBounds.Top;
string line = null;
// Calculate the number of lines per page.
linesPerPage = ev.MarginBounds.Height /
printFont.GetHeight(ev.Graphics);
// Print each line of the file.
while (count < linesPerPage &&
((line = sr.ReadLine()) != null))
{
yPos = topMargin + (count *
printFont.GetHeight(ev.Graphics));
ev.Graphics.DrawString(line, printFont, Brushes.Black,
leftMargin, yPos, new StringFormat());
count++;
}
// If more lines exist, print another page.
if (line != null)
ev.HasMorePages = true;
else
ev.HasMorePages = false;
}

c# - print RichTextBox text with correct spacing

I am making a program that can write in Bengali (a virtual keyboard) or in English. Everything was perfect until I started programming the printing. The user should be able to select any text and change the font and color. Because every character could be different, I need to print character by character. Here is my code:
private void printToolStripMenuItem_Click(object sender, EventArgs e)
{
PrintDialog print = new PrintDialog();
doc = new System.Drawing.Printing.PrintDocument();
print.Document = doc;
doc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDoc);
if (print.ShowDialog() == DialogResult.OK)
{
doc.Print();
}
}
private void printDoc(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
System.IO.StringReader reader = new System.IO.StringReader(richTextBox1.Text);
float linesPerPage = 0;
float yPosition = 0;
int count = 0;
float leftMargin = e.MarginBounds.Left;
float rightMargin = e.MarginBounds.Right;
float topMargin = e.MarginBounds.Top;
string line = null;
Font printFont = this.richTextBox1.Font;
SolidBrush printBrush = new SolidBrush(Color.Black);
int charpos = 0;
int xPosition = (int)leftMargin;
linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics);
while (count < linesPerPage && ((line = reader.ReadLine()) != null))
{
xPosition = (int)leftMargin;
yPosition = topMargin + (count * printFont.GetHeight(e.Graphics));
count++;
for (int i = 0; i < line.Length; i++)
{
richTextBox1.Select(charpos, 1);
if ((xPosition + ((int)e.Graphics.MeasureString(richTextBox1.SelectedText, richTextBox1.SelectionFont).Width)) > rightMargin)
{
count++;
if (!(count < linesPerPage))
{
break;
}
xPosition = (int)leftMargin;
yPosition = topMargin + (count * printFont.GetHeight(e.Graphics));
}
printBrush = new SolidBrush(richTextBox1.SelectionColor);
e.Graphics.DrawString(richTextBox1.SelectedText, richTextBox1.SelectionFont, printBrush, new PointF(xPosition, yPosition));
xPosition += ((int)e.Graphics.MeasureString(richTextBox1.SelectedText, richTextBox1.SelectionFont).Width);
charpos++;
}
}
if (line != null)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
printBrush.Dispose();
}
}
However, when I get a print preview, it shows a space between each of the the characters:
I think this is because e.Graphics.MeasureString() is not giving me the tightest bounding box possible, or it's not giving me the exact width of the character as specified by the font. I'm quite new to C# Anyone know of a way to get the exact width of a character? It's been stumping me for a long time.
According to this MSDN article:
The (Graphics Class) MeasureString method is designed for use with individual string and includes a small amount of extra space before and after the string to allow for overhanging glyphs
You can instead use TextRenderer.MeasureString() to get the precise font width.
GOT IT. Finally. You need to use e.Graphics.MeasureString() after all. Just another overload of it. Use this:
e.Graphics.MeasureString(richTextBox1.SelectedText, richTextBox1.SelectionFont, new PointF(xPosition, yPosition), StringFormat.GenericTypographic).Width;
To remove the space you need to pass StringFormat.GenericTypographic. Hope it helps. (you can use my code for printing text with different color and text if you replace e.Graphics.MeasureString(string, Font) with the above).

Categories

Resources