WPF DocumentViewer Print Landscape Content Cut Off - c#

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.

Related

Remove PDF left and right margins/whitespace when converting to .txt file using C#/Spire.PDF NuGet Package

So I am trying to convert a standard A4 PDF file into a .txt file using Spire.Pdf NuGet Package, and whenever I do it there is a lot of whitespace at the start of each line where the margins of the document go I presume. I managed to solve the issue using the TrimStart() method but I want to be able to do remove the margins using Spire.Pdf itself.
I have played around with setting a PdfTextExtractOptions ExtractArea RectangleF but for some reason it cuts the bottom of the text and I lose rows.
My code is:
PdfDocument doc = new PdfDocument();
doc.LoadFromFile(#"path");
var content = new List<string>();
RectangleF rectangle = new RectangleF(45, 0, 0, 0);
PdfTextExtractOptions options = new() { IsExtractAllText = true, IsShowHiddenText = true, ExtractArea = rectangle };
foreach (PdfPageBase page in doc.Pages)
{
PdfTextExtractor textExtractor = new(page);
//extract text from a specific rectangular area here - defualt A4 margin sizes?
string extractedText = textExtractor.ExtractText(options);
content.Add(extractedText);
}
FileStream fs = new FileStream(#"outputFile.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
string txtBefore = (string.Join("\n", content));
sw.Write(txtBefore);
Thanks in advance
You can try the code below to extract text from PDF, it will not generate extra white spaces at the start of each line in the result .txt file. I already tested it.
PdfDocument doc = new PdfDocument();
doc.LoadFromFile(#"test.pdf");
PdfTextExtractOptions options = new PdfTextExtractOptions();
options.IsSimpleExtraction = true;
StringBuilder sb = new StringBuilder();
foreach (PdfPageBase page in doc.Pages)
{
PdfTextExtractor extractor = new PdfTextExtractor(page);
sb.AppendLine(extractor.ExtractText(options));
}
File.WriteAllText("Extract.txt", sb.ToString());

How to write Arabic text using MigraDoc?

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.

bootstrap css file makes smaller my document when i convert html to PDF with itextsharp in c# Winforms

I am trying to build a customized PDF export form with HTML and bootstrap to use in any c# project. I want to use bootstrap designs to make my custom PDF designs. There is no problem with my own custom css file. It is working fine. But when I add the css file of bootstrap, it makes my document zoom out and be much smaller too. I cannot figure out how to fix this. I just want to create an A4 paper size form in PDF and print it.
Here is what I get when I add the bootstrap css file:
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using iTextSharp.tool.xml.html;
using iTextSharp.tool.xml.parser;
using iTextSharp.tool.xml.pipeline.css;
using iTextSharp.tool.xml.pipeline.end;
using iTextSharp.tool.xml.pipeline.html;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace pdf
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
byte[] result;
Document documment = new Document(PageSize.A4);
string bootstrapCssFilePath = #"C:/Users/sea_h/Desktop/cop/fulhtml/pdf/bootstrap.min.css";
string customCssFilePath = #"C:/Users/sea_h/Desktop/cop/fulhtml/pdf/custom.css";
string htmlText = #"
<html>
<head>
</head>
<body>
<div class='container'>
<col-sm4>
<h1>Deneme H1</h1>
</col-sm4>
<col-sm4>
<h2>deneme h2</h2>
</col-sm4>
<col-sm4>
<h7>deneme h7</h7>
</col-sm4>
</div>
</body>
</html>";
using (var ms=new MemoryStream())
{
PdfWriter writer = PdfWriter.GetInstance(documment, ms);
writer.CloseStream = false;
documment.Open();
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
cssResolver.AddCssFile(bootstrapCssFilePath, true);
cssResolver.AddCssFile(customCssFilePath, true);
IPipeline pipeLine = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(documment, writer)));
XMLWorker worker = new XMLWorker(pipeLine, true);
XMLParser xmlParser = new XMLParser(worker);
xmlParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(htmlText)));
documment.Close();
result = ms.GetBuffer();
string dest = #"C:\Users\sea_h\Desktop\deneme016.pdf";
System.IO.File.WriteAllBytes(dest, result);
}
}
}
}
My custom css is:
h1{
background-color:red;
}
There is no error message.
First you need a button or something to trigger the print job, then toss on some code like this, essentially this is just going pop a print menu and go ahead with print job when user hits submit (returns 1)
In the printImage method you are going to find the declarations for fonts etc you intend to use. I'm sure there are other ways, but I use rectangles to place my draw strings where I need them. tempPoint.X and tempPoint.Y are followed by rect.location = tempPoint, this allows you to move the rectangle around as needed and keep tracking of coordinates as you go. e.graphics.drawstring() is what actually writes the text, for more specifics I would go ahead and look up some further information. From this you can just keep replicating the tempPoint movement, rect location assignment, and drawstring to customize where things are placed in your print form. As far as turning it into a pdf, windows comes with tools that are in the print menu to automate that part of it all.
private void Button1_Click(object sender, EventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(PrintImage);
PrintDialog printdlg = new PrintDialog();
/*preview the assigned document or you can create a different previewButton for it
printPrvDlg.Document = pd;
printPrvDlg.ShowDialog(); // this shows the preview and then show the Printer Dlg below
*/
printdlg.Document = pd;
if (printdlg.ShowDialog() == DialogResult.OK)
{
pd.Print();
}
}
void PrintImage(object o, PrintPageEventArgs e)
{
const int ORIGIN = 150;
var near = new StringFormat() { Alignment = StringAlignment.Near };
var centered = new StringFormat() { Alignment = StringAlignment.Center };
var far = new StringFormat() { Alignment = StringAlignment.Far };
Point tempPoint = new Point();
var rect = new RectangleF(0, 0, 0, 0);
var headingRect = new RectangleF(0, 0, 0, 0);
// Create font and brush.
Font titleDrawFont = new Font("Times New Roman", 16, FontStyle.Bold);
Font subtitleDrawFont = new Font("Times New Roman", 12);
Font drawFont = new Font("Times New Roman", 8);
SolidBrush drawBrush = new SolidBrush(Color.Black);
Pen blackPen = new Pen(Color.Black, 1);
// Draw string to screen.
//***************************************************************
Image logo = Image.FromFile(imageLoc);
e.Graphics.DrawImage(logo, (e.PageBounds.Width - logo.Width) / 2,
10, logo.Width, logo.Height); //Created Centered Image in original size
rect.Width = 150;
rect.Height = 20;
headingRect.Width = e.PageBounds.Width;
headingRect.Height = 40; //Set to 40 to avoid cut off with larger title text
tempPoint.X = 0;
tempPoint.Y = 110;
headingRect.Location = tempPoint;
e.Graphics.DrawString(lblTitle.Text, titleDrawFont, drawBrush, headingRect, centered);
So i just figure out why this is happenning.
Bootstrap css file using rem units for sizing.
But itextsharp using 300ppi resulotion whic means A4 paper have 2480 px X 3508 px resulotion in 300ppi.And bootstrap sizing is so small for this resulotion.
So i can modify bootstrap css file with new higher sizes as manually to fix this problem.
Or if it is possible, i can try the set itextsharp paper ppi for lower as like 70ppi.
I think there is no clear solution for this problem.

issue in exporting image to pdf

m having a grid: companysnapshot.. that grid is exported to disk then its again taken from disk and exported to the pdf.
Below code is working fine and export with the image is done. bt issues is that..
-->image is saved from UI is black background..when its exported is changing in white background( may be its getting converted to png)
--> i want to align the coordinates of the image in the pdf page
is there any way to either increase the width of the image or pdf page.
m a newbie to this ...it would be helpful if someone code me out for this a little.
private void PrepareDocument(RadDocument document)
{
document.SectionDefaultPageOrientation = PageOrientation.Landscape;
document.LayoutMode = DocumentLayoutMode.Paged;
document.Measure(RadDocument.MAX_DOCUMENT_SIZE);
document.Arrange(new RectangleF(PointF.Empty, document.DesiredSize));
}
chart document part:
private void CreateChartDocumentPart(RadDocument document, Grid whGrid, Grid companysnapshot, Grid chartgridimage)
{
Telerik.Windows.Documents.Model.Section section = new Telerik.Windows.Documents.Model.Section();
Telerik.Windows.Documents.Model.Paragraph paragraph = new Telerik.Windows.Documents.Model.Paragraph();
Telerik.Windows.Documents.Model.Span span1;
using (MemoryStream ms = new MemoryStream())
{
companysnapshot.Measure(new System.Windows.Size(double.PositiveInfinity, double.PositiveInfinity));
int companywidth = (int)Math.Round(companysnapshot.ActualWidth);
int companyheight = (int)Math.Round(companysnapshot.ActualHeight);
companywidth = companywidth == 0 ? 1 : companywidth;
companyheight = companyheight == 0 ? 1 : companyheight;
RenderTargetBitmap rtbmp = new RenderTargetBitmap(companywidth, companyheight, 96d, 96d, PixelFormats.Default);
rtbmp.Render(companysnapshot);
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtbmp));
FileStream fs1 = File.Create(#"C:\Users\Admin\Desktop\Chart12xx.bmp");
encoder.Save(fs1);
fs1.Close();
// this.ExportPNGToImage(chart, ms);
paragraph.LeftIndent = 0;
paragraph.RightIndent = 0.0;
FileStream ss = File.Open(#"C:\Users\Admin\Desktop\Chart12xx.bmp", FileMode.Open);
ImageInline image = new ImageInline(ss, new Size(companywidth, companyheight), "bmp");
paragraph.FlowDirection = FlowDirection.LeftToRight;
paragraph.Inlines.Add(image);
ss.Close();
//Span spacespan = new Span(" ");
//paragraph.Inlines.Add(spacespan);
}
try
{
section1.Blocks.Add(paragraph);
document.Sections.Add(section1);
}
catch (Exception)
{
}
// paragraph.Inlines.Add(new Span(FormattingSymbolLayoutBox.LINE_BREAK));
}
issue is solved.. by switching from telerik export to itextsharp for pdf export.

WPF to XPS in landscape orientation

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.

Categories