Как лучше всего печатать материал из C# /. Net?
Вопрос касается как отдельных страниц, так и отчетов, содержащих много страниц.
Было бы здорово получить список наиболее распространенных библиотек печати, содержащих основные функции и подводные камни каждой из них.
[Обновление] для стандартных клиентов (или серверов) Windows, а не для веб-приложений, пожалуйста.
Я просмотрел несколько способов печати, но прежде чем углубиться в один из них, я хотел бы узнать больше - выбирать неправильный способ для получения дополнительных сведений - огромная трата времени.





Для отчетов я использую элемент управления RDLC.
Для всего остального я использую встроенные объекты печати в .NET.
Редактировать Все присущие объекты печати находятся в пространстве имен System.Drawing.Printing. Когда вы используете PrintDialog или PrintPreviewDialog в приложении WinForms (или WPF), вы передаете управление именно этим объектам.
Основная идея заключается в том, что вы рисуете на принтере. Самая простая форма этого:
Sub MyMethod()
Dim x as New PrintDocument
AddHandler x.PrintPage, AddressOf printDoc_PrintPage
x.Print
End Sub
Sub printDoc_PrintPage( sender as Object, e as PrintPageEventArgs)
Dim textToPrint as String= ".NET Printing is easy"
dim printFont as new Font("Courier New", 12)
dim leftMargin as int= e.MarginBounds.Left
dim topMargin as int = e.MarginBounds.Top
e.Graphics.DrawString(textToPrint, printFont, Brushes.Black, leftMargin, topMargin)
End Sub
Что здесь происходит, так это то, что когда моему объекту (x) отправляется команда печати, он вызывает событие «PRINT PAGE» (которое предназначено для печати по одной странице за раз). Затем это событие использует атрибут Graphics объекта PrintPageEventArgs для рисования соответствующей строки непосредственно в диспетчере очереди печати.
Вот один урок, а быстрый поиск в Google «Учебник по печати .NET» возвращает чуть более 200 000 результатов.
Не могли бы вы немного подробнее рассказать о присущих объектам печати?
Это во многом зависит от требований вашего приложения.
Несмотря на то, что это не идеальный инструмент (на самом деле далеко не так), Crystal Reports, как правило, является хорошим выбором. Это дает вам возможность получать данные непосредственно из базы данных или, если у вас уже есть список объектов, которые вы хотите распечатать, вы можете передать их в документ и привязать свойства объекта к меткам отчета.
Но дайте нам больше информации о том, что вы пытаетесь сделать, чтобы вы могли получать лучшие предложения.
Ну да ладно, ко мне приходит куча печатных материалов: отдельные страницы, длинные отчеты, липкие этикетки, назовите это, мне придется распечатать (скоро). Итак, я хотел бы получить обзор решений для печати за и против.
Мы использовали набор сторонних DLL из PDFSharp, которые, в свою очередь, используют библиотеки DLL из MigraDoc. Я не осведомлен обо всех причинах, по которым мы пошли в этом направлении (решение было принято старшим разработчиком), но могу сказать вам следующее:
Вы скажете, что много всего. Хм, похоже, вам следует использовать решение с дизайнером, поэтому вам следует изучить Crystal Reports и RDLC. Также существует решение служб Reporting Services, но в этом случае вам понадобится сервер с SQL Server.
Crystal Reports, кажется, дает вам больше возможностей, но требует немного большего обучения, чем RDLC.
Я бы не рекомендовал вам создавать их в HTML + CSS из-за ограничений и дополнительной работы, которую вам придется выполнить.
Если вы можете создать свой вывод как FlowDocument, вы можете легко превратить его в XPS, чтобы получить «электронную» версию и распечатать XPS.
»Пример кода, демонстрирующий основы печати в приложениях Windows Forms:
using System.Drawing.Printing;
PrintDocument printDoc = new PrintDocument();
printDoc.DefaultPageSettings.Landscape = true;
printDoc.DefaultPageSettings.Margins.Left = 100; //100 = 1 inch = 2.54 cm
printDoc.DocumentName = "My Document Name"; //this can affect name of output PDF file if printer is a PDF printer
//printDoc.PrinterSettings.PrinterName = "CutePDF";
printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDoc; //Document property must be set before ShowDialog()
DialogResult dialogResult = printDialog.ShowDialog();
if (dialogResult == DialogResult.OK)
{
printDoc.Print(); //start the print
}
void printDoc_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
string textToPrint = ".NET Printing is easy";
Font font = new Font("Courier New", 12);
// e.PageBounds is total page size (does not consider margins)
// e.MarginBounds is the portion of page inside margins
int x1 = e.MarginBounds.Left;
int y1 = e.MarginBounds.Top;
int w = e.MarginBounds.Width;
int h = e.MarginBounds.Height;
g.DrawRectangle(Pens.Red, x1, y1, w, h); //draw a rectangle around the margins of the page, also we can use: g.DrawRectangle(Pens.Red, e.MarginBounds)
g.DrawString(textToPrint, font, Brushes.Black, x1, y1);
e.HasMorePages = false; //set to true to continue printing next page
}
Я использую стандартные библиотеки, такие как System.Diagnostics.ProcessStartInfo, чтобы использовать Adobe Acrobat для печати PDF-файла. Конечному пользователю не придется взаимодействовать с графическим интерфейсом Acrobat, хотя, что досадно, следующий код по-прежнему выводит его на экран в течение нескольких секунд.
// Sample fileName = System.Environment.GetFolderPath(
// System.Environment.SpecialFolder.CommonApplicationData)
// + @"\MyCompany\MyProject\TestPrint.pdf"
private void SendPrintJob(string fileName)
{
try
{
// Start by finding Acrobat from the Registry.
// This supposedly gets whichever you have of free or paid
string processFilename = Microsoft.Win32.Registry.LocalMachine
.OpenSubKey("Software")
.OpenSubKey("Microsoft")
.OpenSubKey("Windows")
.OpenSubKey("CurrentVersion")
.OpenSubKey("App Paths")
.OpenSubKey("AcroRd32.exe")
.GetValue(String.Empty).ToString();
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = processFilename;
info.Arguments = String.Format("/p /h {0}", fileName);
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.UseShellExecute = false;
Process p = new Process();
p.StartInfo = info;
p.Start();
p.WaitForInputIdle();
// Recommended to add a time-out feature. Mine is coded here.
}
catch (Exception e)
{
Console.WriteLine("Error sending print job. " + e.Message);
}
Я не читал манипуляции с документами в OP, но я вижу другие ответы, комментирующие этот факт. В нескольких вопросах и ответах на StackOverflow за 2008-2012 гг. (Включая @Robert Gowland из этого вопроса) говорится, что у PDFSharp / MigraDoc плохая документация.
В 2018 году я обнаружил, что это легкая кривая обучения, с множеством примеров в домашняя страница. Я прочитал этот вопрос сегодня утром, чтобы понять, как распечатать график, и теперь у меня есть кнопка, чтобы сделать снимок экрана моего приложения и распечатать его.
Вам нужно будет перейти к диспетчеру пакетов NuGet для PDFsharp-MigraDocs (или PDFsharp-MigraDocs-WPF, или PDFsharp-MigraDocs-GDI). MigraDocs - это высокоуровневый компонент, который может создавать документы из элементов, не заботясь о том, являются ли они pdf, изображением или чем-то еще. PDFSharp - это компонент, который помогает, например, переупорядочивать документы, размещать несколько документов на странице и разделять содержимое с одной на две страницы.
Сколько вы уже смотрели на пространство имен System.Drawing.Printing?