提问人:V.d.S Wim 提问时间:3/24/2023 最后编辑:V.d.S Wim 更新时间:4/1/2023 访问量:476
如何使用 .net 6 和 PdfSharpCore 在服务器端打印?
How can I print in server Side with .net 6 and PdfSharpCore?
问:
我想在服务器端打印,但我拥有的代码无法正常工作,并且在互联网上找不到任何解决方案。 我使用 nuget PdfSharpCore(版本 1.3.47)。 问题是我不知道如何将页面转换为可用于打印作业的位图或图像。 我到处添加评论来提供帮助。
这是我的代码:
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using PdfSharpCore.Pdf;
using PdfSharpCore.Pdf.IO;
/// <summary>
/// The following code takes in a byte array of a PDF file, a printer name, a job name
/// (optional), and a boolean flag for whether to print in color or black and white. It then
/// prints the PDF file using the specified printer.
/// </summary>
/// <param name="pdfBytes">
/// </param>
/// <param name="printerName">
/// </param>
/// <param name="jobName">
/// </param>
/// <param name="isColor">
/// </param>
public void PrintPdf(byte[] pdfBytes, string printerName, string? jobName = null, bool isColor = true)
{
// Use a memory stream to read the PDF bytes
using (var pdfStream = new MemoryStream(pdfBytes))
{
// Use PdfSharp to open the PDF document
using (var doc = PdfReader.Open(pdfStream))
{
// Check if we are running on Windows
if (OperatingSystem.IsWindows())
{
// Only execute the following code if running on Windows
// Use PrintDocument to manage printing
using (var pd = new PrintDocument())
{
// Set the printer name
pd.PrinterSettings.PrinterName = printerName;
// Check if printer exists
if (!pd.PrinterSettings.IsValid)
{
// If the specified printer is not valid, use the default printer
pd.PrinterSettings.PrinterName = PrinterSettings.InstalledPrinters[0];
// Log all possible printers
foreach (string printer in PrinterSettings.InstalledPrinters)
{
Console.WriteLine(printer);
}
}
// Set the print job name (if provided) or default to "Print Job"
pd.DocumentName = jobName ?? "Print Job";
// Set print settings
pd.DefaultPageSettings.Landscape = false;
pd.DefaultPageSettings.Color = isColor;
// Zero-based index for current page
int currentPage = 0;
// Add a PrintPageEventHandler to handle the printing of each page
pd.PrintPage += (sender, args) =>
{
// Check if the operating system is Windows
if (OperatingSystem.IsWindows())
{
// Get the current page and its size
var page = doc.Pages[currentPage];
var size = new Size((int)page.Width, (int)page.Height);
// Check if the page stream is not null
if (page?.Stream != null)
{
// Render the PDF page as an image and draw it onto the bitmap
using (var pageStream = new MemoryStream(page.Stream.Value))
{
using (var bmp = new Bitmap(pageStream))
{
// Check if the graphics object is not null
if (args?.Graphics != null)
{
try
{
// Draw the image onto the graphics object
// within the page boundaries
args.Graphics.DrawImage(bmp, args.PageBounds);
}
catch (Exception ex)
{
// Handle any exceptions that occur while
// rendering the image
Console.WriteLine($"Error rendering PDF as image: {ex.Message}");
}
}
else
{
Console.WriteLine("Graphics object is null.");
}
}
}
}
else
{
Console.WriteLine("PDF Stream empty.");
}
// Move to the next page
currentPage++;
// Set HasMorePages to true if there are more pages to print
if (args != null)
{
args.HasMorePages = currentPage < doc.PageCount;
}
}
else
{
// Code for other operating systems
}
};
// Execute the Print Event
pd.Print();
}
}
else
{
// Code for other operating systems
}
}
}
}
答:
1赞
I liked the old Stack Overflow
3/28/2023
#1
使用 PdfSharpCore,您无法将 PDF 转换为位图,也无法将 PDF 发送到打印机。
您将需要另一个库来将 PDF 页面转换为位图。图书馆推荐在 SO 上是一件困难的事情,所以我不会在这里推荐任何内容。
使用 PDFsharp(移植 PdfSharpCore 的库),您可以使用相同的代码同时创建 PDF 和打印。打印输出不能包含 PDF 页面中的元素,因为 PDFsharp 无法处理。我不知道你的PDF是从哪里来的。如果 PDF 是从您的代码创建的,这可能是您的一个选项。仅在 Windows 下有效的选项。
服务器端打印的一个缺点是打印输出将在服务器站点上生成,而不是在客户端站点上生成。许多网站只是提供 PDF 并让客户进行打印。
2赞
Shloime Rosenblum
4/1/2023
#2
您可以使用 Ghostscript.NET 打印 pdf。
您需要将 pdf 保存到临时文件并使用 ghostscript 库进行打印。
您需要将gsdll32.dll放在项目中的某个目录中,设置路径new GhostscriptVersionInfo("")
我没有测试颜色/灰度是否有效,可能是您需要在打印前将文件转换为灰度。而且我还不知道如何设置作业名称。
/// <summary>
/// The following code takes in a byte array of a PDF file, a printer name, a job name
/// (optional), and a boolean flag for whether to print in color or black and white. It then
/// prints the PDF file using the specified printer.
/// </summary>
/// <param name="pdfBytes">
/// </param>
/// <param name="printerName">
/// </param>
/// <param name="jobName">
/// </param>
/// <param name="isColor">
/// </param>
public void PrintPdf(byte[] pdfBytes, string printerName, string? jobName = null, bool isColor = true)
{
GhostscriptVersionInfo ghostscriptVersion = new GhostscriptVersionInfo("gs/gsdll32.dll");
string inputFile = Path.GetTempFileName() + ".pdf";
File.WriteAllBytes(inputFile, pdfBytes);
try
{
using (GhostscriptProcessor processor = new GhostscriptProcessor(ghostscriptVersion, true))
{
List<string> switches = new List<string>();
switches.Add("-empty");
switches.Add("-dPrinted");
switches.Add("-dDuplex");
if (isColor)
{
switches.Add("-sOutputICCProfile=default_cmyk.icc");
}
switches.Add("-dTumble=0");
switches.Add("-dBATCH");
switches.Add("-dNOPAUSE");
switches.Add("-dNOSAFER");
switches.Add("-dAutoRotatePages=/All");
switches.Add("-sDEVICE=mswinpr2");
switches.Add("-dNoCancel");
switches.Add("-sOutputFile=%printer%" + printerName);
switches.Add("-f");
switches.Add(inputFile);
processor.StartProcessing(switches.ToArray(), null);
}
}
catch (Exception e)
{
MessageBox.Show("Error printing file. \nOriginal message: " + e.Message);
}
finally
{
if (File.Exists(inputFile))
{
File.Delete(inputFile);
}
}
}
}
评论
1赞
I liked the old Stack Overflow
4/4/2023
问题是关于使用 PdfSharpCore 进行打印。这个答案为游戏带来了两个新库,Ghostscript.NET 和 Ghostscript。更复杂的是,这两个库使用不同的许可证。PDFsharp 的许可证非常宽松,对于许多项目来说,具有更严格许可证的库将不是一个选择。
1赞
Shloime Rosenblum
4/19/2023
虽然这可能是也可能不是 OP 正在寻找的答案,但它肯定会对遇到类似问题的其他人有所帮助
评论