Is there a way to print a PDF and select the paper tray to use programmatically?
I'm open to suggestions such as converting the PDF to a different format and printing from there.
I can print to the correct tray using PaperSource() and PrintDocument() is it possible to convert PDFs into a format that these functions can understand?
Thanks.
Based on getting the paper tray PaperSource from something like here on MSDN, if you don't mind using Ghostscript.NET, this should work for you:
public void PrintPdf(string filePath, string printQueueName, PaperSource paperTray)
{
using (ManualResetEvent done = new ManualResetEvent(false))
using (PrintDocument document = new PrintDocument())
{
document.DocumentName = "My PDF";
document.PrinterSettings.PrinterName = printQueueName;
document.DefaultPageSettings.PaperSize = new PaperSize("Letter", 850, 1100);
document.DefaultPageSettings.PaperSource = paperTray;
document.OriginAtMargins = false;
using (var rasterizer = new GhostscriptRasterizer())
{
var lastInstalledVersion =
GhostscriptVersionInfo.GetLastInstalledVersion(
GhostscriptLicense.GPL | GhostscriptLicense.AFPL,
GhostscriptLicense.GPL);
rasterizer.Open(filePath, lastInstalledVersion, false);
int xDpi = 96, yDpi = 96, pageNumber = 0;
document.PrintPage += (o, p) =>
{
pageNumber++;
p.Graphics.DrawImageUnscaledAndClipped(
rasterizer.GetPage(xDpi, yDpi, pageNumber),
new Rectangle(0, 0, 850, 1100));
p.HasMorePages = pageNumber < rasterizer.PageCount;
};
document.EndPrint += (o, p) =>
{
done.Set();
};
document.Print();
done.WaitOne();
}
}
}
Related
I'm trying to edit a paragraph in pptx through changing its text, font size, font style and alignment.
This is what i have done so far:
**this is the method im using to call the update paragraph**
public static void Main(string[] args)
{
using (PresentationDocument presentationDocument = PresentationDocument.Open("ppturl", true))
{
// Get the presentation part of the presentation document.
PresentationPart presentationPart = presentationDocument.PresentationPart;
// Verify that the presentation part and presentation exist.
if (presentationPart != null && presentationPart.Presentation != null)
{
// Get the Presentation object from the presentation part.
Presentation presentation = presentationPart.Presentation;
// Verify that the slide ID list exists.
if (presentation.SlideIdList != null)
{
SlideId sourceSlide = presentation.SlideIdList.ChildElements[0] as SlideId;
SlidePart slidePart = presentationPart.GetPartById(sourceSlide.RelationshipId) as SlidePart;
updateParagraph(slidePart);
}
}
}
Console.ReadLine();
CreateHostBuilder(args).Build().Run();
}
**Here im extracting the title in the slide because this is what i need.**
public static void updateParagraph(SlidePart slidePart)
{
if (slidePart == null)
{
throw new ArgumentNullException("presentationDocument");
}
if (slidePart.Slide != null)
{
// Find all the title shapes.
var shapes = from shape in slidePart.Slide.Descendants<Shape>()
where IsTitleShape(shape)
select shape;
foreach (P.Shape shape in shapes)
{
D.Paragraph paragraph = shape.TextBody.Elements<D.Paragraph>().FirstOrDefault();
shape.TextBody.RemoveAllChildren<D.Paragraph>();
AddNewParagraph(shape, "This is a new Slide");
}
}
}
**This is where i am trying to add a new paragraph with specific style**
public static void AddNewParagraph(this P.Shape shape, string NewText)
{
D.Paragraph p = new D.Paragraph();
P.TextBody docBody = shape.TextBody;
Justification justification1 = new Justification() { Val = JustificationValues.Center };
p.ParagraphProperties=new D.ParagraphProperties(justification1);
D.Run run = new D.Run(new D.Text(NewText));
D.RunProperties runProp = new D.RunProperties() { Language = "en-US", FontSize = 9, Dirty = false };
run.AppendChild(runProp);
D.Text newText = new D.Text(NewText);
run.AppendChild(newText);
Console.WriteLine("--------------------------------------------------------------");
Console.WriteLine(runProp.FontSize.ToString());
Console.WriteLine("--------------------------------------------------------------");
p.Append(run);
docBody.Append(p);
}
This is giving me an error whenever im trying to open the pptx "repair pptx error".
Can someone please provide a clear solution specific to pptx and not doc.?
Thankful..
You can try using Aspose.Slides for .NET. The following code example shows you how to change some paragraph properties with this library:
using (var presentation = new Presentation("example.pptx"))
{
var firstShape = (IAutoShape) presentation.Slides[0].Shapes[0];
var firstParagraph = firstShape.TextFrame.Paragraphs[0];
var firstPortion = firstParagraph.Portions[0];
firstPortion.Text = "New text.";
firstPortion.PortionFormat.FontHeight = 24;
firstPortion.PortionFormat.FontBold = NullableBool.True;
firstParagraph.ParagraphFormat.Alignment = TextAlignment.Center;
presentation.Save("example.pptx", SaveFormat.Pptx);
}
You can also evaluate Aspose.Slides Cloud SDK for .NET. This REST-based API allows you to make 150 free API calls per month for API learning and presentation processing. The following code example shows you how to change the paragraph settings using Aspose.Slides Cloud:
var slidesApi = new SlidesApi("my_client_id", "my_client_key");
var fileName = "example.pptx";
var slideIndex = 1;
var shapeIndex = 1;
var paragraphIndex = 1;
var portionIndex = 1;
var firstPortion = slidesApi.GetPortion(
fileName, slideIndex, shapeIndex, paragraphIndex, portionIndex);
firstPortion.Text = "New text.";
firstPortion.FontHeight = 24;
firstPortion.FontBold = Portion.FontBoldEnum.True;
slidesApi.UpdatePortion(
fileName, slideIndex, shapeIndex, paragraphIndex, portionIndex, firstPortion);
var firstParagraph = slidesApi.GetParagraph(
fileName, slideIndex, shapeIndex, paragraphIndex);
firstParagraph.Alignment = Paragraph.AlignmentEnum.Center;
slidesApi.UpdateParagraph(
fileName, slideIndex, shapeIndex, paragraphIndex, firstParagraph);
I work as a Support Developer at Aspose.
I used pdfiumViewer to print a label created by itextshape, i finded this code in stackoverflow, it's work good for A4 paper but for custom paper like my label the problem going to happening. This is code:
public static void PrintPDF(string printer, string paperName, string filename, int copies, bool isduplex = false, bool isHorizontal = false, bool printLabel = false)
{
try
{ // Create the printer settings for our printer
var printerSettings = new PrinterSettings
{
PrinterName = printer,
Copies = (short)copies,
Duplex = Duplex.Simplex,
};
if (isduplex && printerSettings.CanDuplex && isHorizontal)
{
printerSettings.Duplex = Duplex.Horizontal;
}
if (isduplex && printerSettings.CanDuplex && isHorizontal == false)
{
printerSettings.Duplex = Duplex.Vertical;
}
// Create our page settings for the paper size selected
var pageSettings = new PageSettings(printerSettings)
{
};
if (printLabel == true)
{
PaperSize paper = new PaperSize("label", 460, 260);
pageSettings.PaperSize = paper;
pageSettings.Margins = new Margins(0, 0, 0, 0);
}
else
{
foreach (PaperSize paperSize in printerSettings.PaperSizes)
{
if (paperSize.PaperName == paperName)
{
pageSettings.PaperSize = paperSize;
break;
}
}
}
// Now print the PDF document
if (printerSettings.IsValid)
{
using (var document = PdfiumViewer.PdfDocument.Load(filename))
{
using (var printDocument = document.CreatePrintDocument(PdfiumViewer.PdfPrintMode.CutMargin))
{
printDocument.PrintController = new StandardPrintController();
printDocument.OriginAtMargins = true;
printDocument.PrinterSettings = printerSettings;
printDocument.DefaultPageSettings = pageSettings;
printDocument.Print();
}
}
}
}
catch
{
throw;
}
}
The problem is the HardMarginX alway is 20. It is readonly properties so i can not change. So when i print, paper alway margin left some space. So anyway i can do to fix this problem.
Thank for reading
PaperSize paperSize = new PaperSize("Test", 315, 300);
paperSize.RawKind = (int)PaperKind.Custom;
Using This Code
i'm developing an app in wpf that is printing photos in a loop, so I would like to get actual moment when the job i really done and I can proceed to another.
I'm printing using PrintDocument class, I tried EndPrint event but it is hit when file is sent to the printer, not when printer did its job. Also in system queue the document disappears before end of printing. Is it possible to get some how information of status of printer?
PrintDocument pd = new PrintDocument();
PrinterSettings.PaperSizeCollection ps = pd.PrinterSettings.PaperSizes;
PaperSize size = new PaperSize();
foreach (PaperSize Psz in ps)
{
if (Psz.PaperName == ev.PaperSize)
{
size = Psz;
break;
}
}
pd.PrinterSettings.PrinterName = ev.printerName;
pd.DefaultPageSettings.PaperSize = size;
pd.DocumentName = "aaaaa";
pd.PrintPage += PrintPage2;
pd.EndPrint += new PrintEventHandler(this.PrintEnd2);
pd.Print();
var myPrintServer = new LocalPrintServer();
var pq = myPrintServer.GetPrintQueue(ev.printerName);
var jobs = pq.GetPrintJobInfoCollection();
foreach (var job in jobs)
{
var done = false;
while (!done)
{
pq.Refresh();
job.Refresh();
done = job.IsCompleted || job.IsDeleted || job.IsPrinted;
}
}
ai++;
PopAction();
It can be find out through PrintSystemJobInfo.IsCompleted.
https://learn.microsoft.com/en-us/dotnet/api/system.printing.printsystemjobinfo.iscompleted?view=netframework-4.7.2
So I have a function that renders a Queue Stream class. Based on a conditional, I would like to add an additional byte array to this queue. I thought I could do this by converting the byte array to a stream, and then Enqueueing it with this additional stream.
I do notice that the count of the streams goes up after enqueueing the original stream, and I pass that into a function that prints the streams. This is where I receive the exception "A generic error occured in GDI+."
EDIT: After going through each page, I realized that when combining the TermsandConditions Byte array to the Stream Queue, it was showing as just one byte Array, where as the T&C's is 2 pdfs.
So my next question is how to convert a pdf to an image?
Here's the function where I'm combining the queues:
internal static void DoPrintInvoice(int orderID, SalesOrderBLL.DocumentType doctype, string printer, int copies, List<string> lines)
{
using (var context = rempscoDataContext.CreateReadOnlyContext())
using (MiniProfiler.Current.Step("DoPrintInvoice()"))
{
// Generate Report
using (var report = GetSalesOrderReport(orderID, _DocumentTypeDescriptions[doctype], doctype != DocumentType.InvoiceLetterhead, lines))
{
// render queue streams for printing
var streams = PrintingBLL.RenderStreams(report, landscape: false);
//add additional byte array to stream.
var TermsAndConditions = GetTermsAndConditions().ToArray();
Stream TCStream = new MemoryStream(TermsAndConditions);
if (doctype == DocumentType.OrderAcknowledgement)
{
streams.Enqueue(TCStream);
}
// render and save pdf in background, print report
BackgroundTask.ParallelInvoke(
() => SaveSalesOrderPDF(orderID, doctype, report),
() => PrintingBLL.PrintStreams(streams, string.Format("Sales Order ({0})", report.DisplayName), printer, copies, false)
);
}
}
}
Then here's the PrintStreams function:
internal static void PrintStreams(Queue<Stream> streams, string documentName, string printer, int copies, bool landscape)
if (copies > 0)
{
// get printer details
using (var pd = new PrintDocument())
{
lock (_PrintLock)
{
pd.PrinterSettings.PrinterName = printer.Trim();
if (!pd.PrinterSettings.IsValid)
throw new ArgumentOutOfRangeException(string.Format("Invalid printer \"{0}\". Please try again with a different printer.", printer));
}
pd.DocumentName = documentName;
pd.PrintController = new StandardPrintController();
pd.PrinterSettings.Copies = (short)copies;
pd.PrinterSettings.Collate = true;
pd.PrinterSettings.DefaultPageSettings.PaperSize = pd.PrinterSettings.PaperSizes.Cast<PaperSize>().First(ps => ps.Kind == PaperKind.Letter);
pd.DefaultPageSettings.Landscape = landscape;
pd.DefaultPageSettings.Margins = new Margins()
{
Top = 0,
Bottom = 0,
Left = 0,
Right = 0,
};
var numPages = streams.Count;
var currentPage = 0;
pd.PrintPage += (s, ev) =>
{
BackgroundTask.SetCurrentStatus(
currentPage / numPages,
string.Format("Printing page {0} of {1}. [{2}]", currentPage, numPages, documentName));
// get next page
var ms = streams.Dequeue();
// if we have any streams left, then we have another page
ev.HasMorePages = streams.Any();
// reset stream
ms.Position = 0;
// read page image
var image = new Metafile(ms);
var r = new Rectangle()
{
X = 0,
Y = 0,
Width = 825,
Height = 1075,
};
if (landscape)
{
r.Height = 825;
r.Width = 1075;
}
// draw image directly on page
ev.Graphics.DrawImage(image, r);
// destroy stream
ms.Close();
currentPage++;
};
try
{
lock (_PrintLock)
pd.Print();
BackgroundTask.SetCurrentStatus(100, string.Format("Finished printing {0}", documentName));
}
catch (Exception e)
{
BackgroundTask.SetCurrentStatus(0, string.Format("Printing Error: {0}", e.Message));
throw new InvalidOperationException(
string.Format("The document failed to print. Arguments were: documentName = {0}; printer = {1}; copies = {2}; landscape = {3}",
documentName,
printer,
copies,
landscape),
e);
}
}
}
}
i am trying to show the barcode in asp.net page. already download the zen barcode render with sample code. i tried the sample it is working fine with me. once i try in my code barcode label is showing empty. i checked with sample code and mine i did not find any difference , only data transfer is the different. this is what i tried.
<barcode:BarcodeLabel ID="BarcodeLabel1" runat="server" BarcodeEncoding="Code39NC" LabelVerticalAlign="Bottom" Text="12345"></barcode:BarcodeLabel>
if (!IsPostBack)
{
List<string> symbologyDataSource = new List<string>(
Enum.GetNames(typeof(BarcodeSymbology)));
symbologyDataSource.Remove("Unknown");
barcodeSymbology.DataSource = symbologyDataSource;
barcodeSymbology.DataBind();
}
this is the function
BarcodeSymbology symbology = BarcodeSymbology.Unknown;
if (barcodeSymbology.SelectedIndex != 0)
{
symbology = (BarcodeSymbology)1;
}
symbology = (BarcodeSymbology)1;
string text = hidID.Value.ToString();
string scaleText = "1";
int scale;
if (!int.TryParse(scaleText, out scale))
{
if (symbology == BarcodeSymbology.CodeQr)
{
scale = 3;
}
else
{
scale = 1;
}
}
else if (scale < 1)
{
scale = 1;
}
if (!string.IsNullOrEmpty(text) && symbology != BarcodeSymbology.Unknown)
{
barcodeRender.BarcodeEncoding = symbology;
barcodeRender.Scale = 1;
barcodeRender.Text = text;
}
symbology is set as Code39NC from the dropdown. scale is 1 and text is coming from other form the value is passing as well. still the bacodelable is showing only value not the barcode picture.
Here are two code samples using ZXing to create a (QR) barcode as both an image and as a base64 encoded string. Both of these options can be used with an <img /> tag to embed the barcode in the page.
This is not an ASP.NET control. It is a library that creates barcodes from text.
// First Text to QR Code as an image
public byte[] ToQRAsGif(string content)
{
var barcodeWriter = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = this._h,
Width = this._w,
Margin = 2
}
};
using (var bitmap = barcodeWriter.Write(content))
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Gif);
stream.Position = 0;
return stream.GetBuffer();
}
}
// From Text to QR Code as base64 string
public string ToQRAsBase64String(string content)
{
var barcodeWriter = new BarcodeWriter
{
Format = BarcodeFormat.QR_CODE,
Options = new EncodingOptions
{
Height = _h,
Width = _w,
Margin = 2
}
};
using (var bitmap = barcodeWriter.Write(content))
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Gif);
return String.Format("data:image/gif;base64,{0}", Convert.ToBase64String(stream.ToArray()));
}
}
Hope this helps! Happy coding.
UPDATE: Here is the link to their product page on codeplex: https://zxingnet.codeplex.com/