I am trying to print from a pdf file which has been generated to replicate a 80mm wide roll printout. Ie the pdf is printed to a custom 80mm wide page type.
I send this file using the code below, it is passed a papername of 80 x 297mm which corresponds to a physical thermal printer paper size. I cannot work out why pdfiumviewer is making the output on the printer scaled down to only being about 20mm wide on the 80mm wide paper When I print the PDF directly from EDGE ot adobe the pdf fits perfectly on the paper. I cannot work out why it is scaling down.
If anyone has a solution or a better way to print PDF silently to a destination printer I am very open to suggestions.
public bool PrintPDF(string printer, string paperName, string filename, int copies)
{
try
{
// Create the printer settings for our printer
var printerSettings = new PrinterSettings
{
PrinterName = printer,
Copies = (short)copies,
};
// Create our page settings for the paper size selected
var pageSettings = new PageSettings(printerSettings)
{
Margins = new Margins(0, 0, 0, 0),
};
foreach (PaperSize papersize in printerSettings.PaperSizes)
{
if (papersize.PaperName == paperName)
{
pageSettings.PaperSize = papersize;
break;
}
}
// Now print the PDF document
using (var document = PdfDocument.Load(filename))
{
using (var printDocument = document.CreatePrintDocument())
{
printDocument.PrinterSettings = printerSettings;
printDocument.DefaultPageSettings = pageSettings;
printDocument.Print();
}
}
return true;
}
catch
{
return false;
}
}
Related
I am using ASP for this and I had to generate reports in PDF format and send the file back to clients so they can download it.
I made the reports using MigraDoc library and they were great but after I tried it with Arabic text I found the texts were in LTR and the characters were disjointed so I made this code to test things out
...............
MigraDoc.DocumentObjectModel.Document reportDoc = new MigraDoc.DocumentObjectModel.Document();
reportDoc.Info.Title = "test";
sec = reportDoc.AddSection();
string fileName = "test.pdf";
addformattedText(sec, "العبارة", true);
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = reportDoc;
renderer.RenderDocument();
MemoryStream pdfStream = new MemoryStream();
renderer.PdfDocument.Save(pdfStream);
byte[] bytes = pdfStream.ToArray();
...............
private void addformattedText(Section sec,string text, bool shouldBeBold = false)
{
var tf = sec.AddTextFrame();
var p = tf.AddParagraph(text);
p.Format.Font.Name = "Tahoma";
if (shouldBeBold) p.Format.Font.Bold = true;
}
I get the output like this
I have tried to encode the text and make it a unicode string using this code
private string getEscapedString(string text)
{
if (true || HasArabicCharacters(text))
{
string uString = "";
byte[] utfBytes = Encoding.Unicode.GetBytes(text);
foreach (var u in utfBytes)
{
if (u != 0)
{
uString += String.Format(#"\u{0:x4}", u);
}
}
return uString;
}
else
return text;
}
and get the returned string into a paragraph and save the PDF documents with unicode parameter set to true
But it is all the same.
I can not figure out how to get it done.
The reports were done using MigraDoc 1.50.5147 library.
The problem is Arabic language font have 4 different shap in begging,last,connected and alone, where Pdfsharp and MigraDoc can not recognize which shap to print farther more you need to reverse the character order to solve this you can use AraibcPdfUnicodeGlyphsResharper to help do such work as following:
using PdfSharp.Drawing;
using PdfSharp.Pdf;
using AraibcPdfUnicodeGlyphsResharper;
namespace MigraDocArabic
{
internal class PrintArabicUsingPdfSharp
{
public PrintArabicUsingPdfSharp(string path)
{
PdfDocument document = new PdfDocument();
document.Info.Title = "Created with PDFsharp";
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
// Create an empty page
PdfPage page = document.AddPage();
// Get an XGraphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(page);
// Create a font
XFont font = new XFont("Arial", 20, XFontStyle.BoldItalic);
var xArabicString = "كتابة اللغة العربية شيئ جميل".ArabicWithFontGlyphsToPfd();
// Draw the text
gfx.DrawString("Hello, World!", font, XBrushes.Black, new XRect(0, 0, page.Width, page.Height), XStringFormats.Center);
gfx.DrawString(xArabicString, font, XBrushes.Black, new XRect(50, 50, page.Width, page.Height), XStringFormats.Center);
// Save the document...
document.Save(path);
}
}
}
Do not Forget the Extension method
By the way this is work with iText7 too
see the image for result
Result
PDFsharp does not support RTL languages yet:
http://www.pdfsharp.net/wiki/PDFsharpFAQ.ashx#Does_PDFsharp_support_for_Arabic_Hebrew_CJK_Chinese_Japanese_Korean_6
You can work around this limitation by reversing the string.
PDFsharp does not support font ligatures yet. You are probably able to work around this limitation by replacing letters with the correct glyph (start, middle, end) depending on the position.
I'm using DocumentViewer in a WPF XAML project. I create a fixed document with the following code. The page looks fine in the viewer. When I print it, it prints in landscape view, but the top 1-2 cm is cut off! I tried it without the scale transform on the dockpanel but that had no effect.
private void PrintReport()
{
PrintDialog pd = new PrintDialog();
pd.PrintQueue = LocalPrintServer.GetDefaultPrintQueue();
pd.PrintTicket = pd.PrintQueue.DefaultPrintTicket;
pd.PrintTicket.PageOrientation = PageOrientation.Landscape;
pd.PrintDocument(docViewer.Document.DocumentPaginator, "DaySheet");
}
public void BuildReport(DockPanel dpPrint)
{
try
{
// init
ScaleTransform st = new ScaleTransform(0.5, 0.5, 0, 0);
dpPrint.RenderTransform = st;
Size pgSize = new Size(96 * 11.69, 96 * 8.27);
FixedDocument fd = new FixedDocument();
// add page content
FixedPage fp = new FixedPage();
fp.Width = pgSize.Width;
fp.Height = pgSize.Height;
fp.Children.Add(dpPrint);
// set page content
PageContent pc = new PageContent();
pc.Child = fp;
fd.Pages.Add(pc);
// set up fresh XpsDocument
var uri = new Uri("pack://daysheet_report.xps");
PackageStore.RemovePackage(uri);
var stream = new MemoryStream();
var package = Package.Open(stream, FileMode.Create, FileAccess.ReadWrite);
PackageStore.AddPackage(uri, package);
var xpsDoc = new XpsDocument(package, CompressionOption.NotCompressed, uri.AbsoluteUri);
// write FixedDocument to the XpsDocument
var docWriter = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
docWriter.Write(fd);
// display XpsDocument in DocumentViewer
docViewer.Document = xpsDoc.GetFixedDocumentSequence();
docViewer.Document.DocumentPaginator.PageSize = pgSize;
}
catch (Exception ex)
{
gFunc.ProcessError(ex);
}
}
I tried playing around with printer drivers but it seemed to make no difference. The printer driver I have installed is the correct one for my laser printer and the right version for Windows 10 64-bit. When I print from Word, Excel, PDF its all fine, but from my WPF app it crops the top part of the page content.
As is so often the case, I got around the problem with a hack. I just changed the page content to use a StackPanel and I placed a blank TextBlock as the first child to push the other content down.
ByteScout PDF Renderer SDK – C# – PDF to TIFF multipaged example in blow, you can convert pdf to multipaged tiff. But I wonder, how can I convert to pages with progress.
using System.Diagnostics;
using Bytescout.PDFRenderer;
namespace PDF2TIFF
{
class Program
{
static void Main()
{
// Create Bytescout.PDFRenderer.RasterRenderer object instance and register it.
RasterRenderer renderer = new RasterRenderer();
renderer.RegistrationName = "demo";
renderer.RegistrationKey = "demo";
// Load PDF document.
renderer.LoadDocumentFromFile("multipage.pdf");
int startPage = 0;
int endPage = renderer.GetPageCount() - 1;
// Save PDF document to black-and-white multi-page TIFF at 120 DPI
RenderingOptions renderingOptions = new RenderingOptions();
renderingOptions.TIFFCompression = TIFFCompression.CCITT4;
renderer.SaveMultipageTiff("multipage.tiff", startPage, endPage, 120, renderingOptions);
// Cleanup
renderer.Dispose();
// Open result document in default associated application (for demo purpose)
ProcessStartInfo processStartInfo = new ProcessStartInfo("multipage.tiff");
processStartInfo.UseShellExecute = true;
Process.Start(processStartInfo);
}
}
}
using System.Diagnostics;
using Bytescout.PDFRenderer;
namespace PDF2TIFF
{
class Program
{
static void Main()
{
// Create Bytescout.PDFRenderer.RasterRenderer object instance and register it.
RasterRenderer renderer = new RasterRenderer();
renderer.RegistrationName = "demo";
renderer.RegistrationKey = "demo";
// Load PDF document.
renderer.LoadDocumentFromFile("multipage.pdf");
// ProgressChanged here...
renderer.ProgressChanged += RasterRenderer_ProgressChanged;
int startPage = 0;
int endPage = renderer.GetPageCount() - 1;
// Save PDF document to black-and-white multi-page TIFF at 120 DPI
RenderingOptions renderingOptions = new RenderingOptions();
renderingOptions.TIFFCompression = TIFFCompression.CCITT4;
renderer.SaveMultipageTiff("multipage.tiff", startPage, endPage, 120, renderingOptions);
// Cleanup
renderer.Dispose();
// Open result document in default associated application (for demo purpose)
ProcessStartInfo processStartInfo = new ProcessStartInfo("multipage.tiff");
processStartInfo.UseShellExecute = true;
Process.Start(processStartInfo);
}
private void RasterRenderer_ProgressChanged(object sender, OngoingOperation og, double p, ref bool cancel)
{
var per = 100 * decimal.Divide(Convert.ToDecimal(p), 100);
label1.Update();
label1.Text = $#"{per:F2}% completed.";
}
}
}
My printing code given below
void SaveReport(Telerik.Reporting.Report report, string fileName)
{
ReportProcessor reportProcessor = new ReportProcessor();
Telerik.Reporting.InstanceReportSource instanceReportSource = new Telerik.Reporting.InstanceReportSource();
instanceReportSource.ReportDocument = report;
RenderingResult result = reportProcessor.RenderReport("PDF", instanceReportSource, null);
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}
// initialize PrintDocument object
PrintDocument doc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
// set the printer to 'Microsoft Print to PDF'
PrinterName = "Canon LBP3000",
// tell the object this document will print to file
// PrintToFile = true,
// set the filename to whatever you like (full path)
PrintFileName = fileName,
}
};
doc.DocumentName = "My";
doc.Print();
}
Then I call the function like
SaveReport(new ThermalPrint(), Server.MapPath(#"~\Report\123.pdf"));
The function executes without error but printer not print the pdf file.
The printer printing dialog like
I can't understand the problem.
If you want to print the report, call reportProcessor.PrintReport(typeReportSource, printerSettings) but make sure you provide a valid PrinterSettings instance.
i am trying to to generate a XPS Document from a WPF Control. Printing works so far, but i cannot find a way to create the XPS in landscape mode.
My code to create the XPS file, mostly taken from another SO page
public FixedDocument ReturnFixedDoc()
{
FixedDocument fixedDoc = new FixedDocument();
PageContent pageContent = new PageContent();
FixedPage fixedPage = new FixedPage();
var ctrl = new controlToPrint();
//Create first page of document
fixedPage.Children.Add(ctrl);
((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
fixedDoc.Pages.Add(pageContent);
//Create any other required pages here
return fixedDoc;
}
public void SaveCurrentDocument()
{
// Configure save file dialog box
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "MyReport"; // Default file name
dlg.DefaultExt = ".xps"; // Default file extension
dlg.Filter = "XPS Documents (.xps)|*.xps"; // Filter files by extension
// Show save file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process save file dialog box results
if (result == true)
{
// Save document
string filename = dlg.FileName;
FixedDocument doc = ReturnFixedDoc();
XpsDocument xpsd = new XpsDocument(filename, FileAccess.Write);
System.Windows.Xps.XpsDocumentWriter xw = XpsDocument.CreateXpsDocumentWriter(xpsd);
xw.Write(doc);
xpsd.Close();
}
}
Any help is appreciated.
Try setting the size of your FixedPage in ReturnFixedDoc:
// hard coded for A4
fixedPage.Width = 11.69 * 96;
fixedPage.Height = 8.27 * 96;
The numbers are in the form (inches) x (dots per inch). 96 is the DPI of WPF. I have used the dimensions of an A4 page.