在仅使用HTML Javascript over HTTP的普通Web应用程序中,您不能直接将文档发送到打印机 . 那台's one of the reasons web browsers exist, and without that functionality everyone'的打印机会收集与公共传真机相同的垃圾 .
PdfFilePrinter p = new PdfFilePrinter();
p.PdfFileName = @"c:\1.pdf";
p.Print();
p.PdfFileName = @"c:\2.pdf";
p.Print();
而且课程是:
public class PdfFilePrinter
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfFilePrinter"/> class.
/// </summary>
public PdfFilePrinter()
{
adobeReaderPath = @"C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe";
printerName = "HP LaserJet P2055 Series PCL6";
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfFilePrinter"/> class.
/// </summary>
/// <param name="pdfFileName">Name of the PDF file.</param>
public PdfFilePrinter(string pdfFileName)
{
this.PdfFileName = pdfFileName;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfFilePrinter"/> class.
/// </summary>
/// <param name="pdfFileName">Name of the PDF file.</param>
/// <param name="printerName">Name of the printer.</param>
public PdfFilePrinter(string pdfFileName, string printerName)
{
this.pdfFileName = pdfFileName;
this.printerName = printerName;
}
/// <summary>
/// Gets or sets the name of the PDF file to print.
/// </summary>
public string PdfFileName
{
get { return this.pdfFileName; }
set { this.pdfFileName = value; }
}
string pdfFileName;
/// <summary>
/// Gets or sets the name of the printer. A typical name looks like '\\myserver\HP LaserJet PCL5'.
/// </summary>
/// <value>The name of the printer.</value>
public string PrinterName
{
get { return this.printerName; }
set { this.printerName = value; }
}
string printerName;
/// <summary>
/// Gets or sets the working directory.
/// </summary>
public string WorkingDirectory
{
get { return this.workingDirectory; }
set { this.workingDirectory = value; }
}
string workingDirectory;
/// <summary>
/// Prints the PDF file.
/// </summary>
public void Print()
{
Print(-1);
}
/// <summary>
/// Prints the PDF file.
/// </summary>
/// <param name="milliseconds">The number of milliseconds to wait for completing the print job.</param>
public void Print(int milliseconds)
{
if (this.printerName == null || this.printerName.Length == 0)
this.printerName = PdfFilePrinter.defaultPrinterName;
if (PdfFilePrinter.adobeReaderPath == null || PdfFilePrinter.adobeReaderPath.Length == 0)
throw new InvalidOperationException("No full qualified path to AcroRd32.exe or Acrobat.exe is set.");
if (this.printerName == null || this.printerName.Length == 0)
throw new InvalidOperationException("No printer name set.");
// Check whether file exists.
string fqName = String.Empty;
if (this.workingDirectory != null && this.workingDirectory.Length != 0)
fqName = Path.Combine(this.workingDirectory, this.pdfFileName);
else
fqName = Path.Combine(Directory.GetCurrentDirectory(), this.pdfFileName);
if (!File.Exists(fqName))
throw new InvalidOperationException(String.Format("The file {0} does not exist.", fqName));
// TODO: Check whether printer exists.
try
{
DoSomeVeryDirtyHacksToMakeItWork();
//acrord32.exe /t <- seems to work best
//acrord32.exe /h /p <- some swear by this version
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = PdfFilePrinter.adobeReaderPath;
string args = String.Format("/t \"{0}\" \"{1}\"", this.pdfFileName, this.printerName);
//Debug.WriteLine(args);
startInfo.Arguments = args;
startInfo.CreateNoWindow = true;
startInfo.ErrorDialog = false;
startInfo.UseShellExecute = false;
if (this.workingDirectory != null && this.workingDirectory.Length != 0)
startInfo.WorkingDirectory = this.workingDirectory;
Process process = Process.Start(startInfo);
if (!process.WaitForExit(milliseconds))
{
// Kill Adobe Reader/Acrobat
process.Kill();
}
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// For reasons only Adobe knows the Reader seams to open and shows the document instead of printing it
/// when it was not already running.
/// If you use PDFsharp and have any suggestions to circumvent this function, please let us know.
/// </summary>
void DoSomeVeryDirtyHacksToMakeItWork()
{
if (PdfFilePrinter.runningAcro != null)
{
if (!PdfFilePrinter.runningAcro.HasExited)
return;
PdfFilePrinter.runningAcro.Dispose();
PdfFilePrinter.runningAcro = null;
}
// Is any Adobe Reader/Acrobat running?
Process[] processes = Process.GetProcesses();
int count = processes.Length;
for (int idx = 0; idx < count; idx++)
{
try
{
Process process = processes[idx];
ProcessModule module = process.MainModule;
if (String.Compare(Path.GetFileName(module.FileName), Path.GetFileName(PdfFilePrinter.adobeReaderPath), true) == 0)
{
// Yes: Fine, we can print.
PdfFilePrinter.runningAcro = process;
break;
}
}
catch { }
}
if (PdfFilePrinter.runningAcro == null)
{
// No: Start an Adobe Reader/Acrobat.
// If you are within ASP.NET, good luck...
PdfFilePrinter.runningAcro = Process.Start(PdfFilePrinter.adobeReaderPath);
PdfFilePrinter.runningAcro.WaitForInputIdle();
}
}
static Process runningAcro;
/// <summary>
/// Gets or sets the Adobe Reader or Adobe Acrobat path.
/// A typical name looks like 'C:\Program Files\Adobe\Adobe Reader 7.0\AcroRd32.exe'.
/// </summary>
static public string AdobeReaderPath
{
get { return PdfFilePrinter.adobeReaderPath; }
set { PdfFilePrinter.adobeReaderPath = value; }
}
static string adobeReaderPath;
/// <summary>
/// Gets or sets the name of the default printer. A typical name looks like '\\myserver\HP LaserJet PCL5'.
/// </summary>
static public string DefaultPrinterName
{
get { return PdfFilePrinter.defaultPrinterName; }
set { PdfFilePrinter.defaultPrinterName = value; }
}
static string defaultPrinterName;
}
7 回答
该问题的关键词是“网络应用程序” .
在仅使用HTML Javascript over HTTP的普通Web应用程序中,您不能直接将文档发送到打印机 . 那台's one of the reasons web browsers exist, and without that functionality everyone'的打印机会收集与公共传真机相同的垃圾 .
所以你需要某种解决方法 . 一种选择是 Build 一个通用的插件,如flash,silverlight,java applet,甚至像greasemonkey . 另一种是自定义插件,如托管的winforms控件或自定义浏览器扩展 .
您非常幸运,因为您看起来已完全控制(或了解)部署环境,并且此环境非常均匀 . 这意味着您还有其他人已经开始探索的其他选项 . 如果您可以将环境中的所有打印机安装到Web服务器,那么使用内置的.Net打印机类(在
System.Drawing.Printing
命名空间中)列出这些打印机相当容易,或者向用户显示它们以便它们可以选择或保留某种IP到打印机映射表,然后从您的Web应用程序直接打印到该打印机 . 请注意,此方案可能要求您的应用程序以比其他方式更高的信任级别运行 .现在,实际打印PDF和Word文档 . 对于acrobat,请检查以下链接:
http://support.adobe.com/devsup/devsup.nsf/docs/52080.htm(Wayback machine)
请注意,它必须尝试一些以确保它按预期工作 .
对于Word,我通常不喜欢Web应用程序中的Office互操作/自动化 . 但在这种情况下,您不会编辑任何文档:只需加载足够长的时间即可打印 . 而你依赖于另一种稀缺资源(打印机)的事实应该使其不会超出你的网络服务器所能应付的范围 . 因此,您可能会遇到一个罕见的情况,即Web项目中的Office自动化是有意义的 .
如今许多打印机和多功能设备都支持直接打印PDF,这可能会解决您的一个问题 . 只需将PDF发送到打印机即可 . 事实上,有些人甚至支持发送URL,然后打印机将获取文档并打印出来 . Lexmark肯定会这样做,我认为其他一些供应商也这样做 . 这仍然意味着你必须处理Word文档 . Word 2007支持PDF(带有add-in installed from Microsoft),我以编程方式使用此函数,在C#中取得了巨大成功 .
这是代码:
最后,如果您的设备不支持PDF打印,那么您可以使用Ghostscript或其他工具将您的PDF转换为PS甚至PCL . 不是最大的,因为这意味着运行一些非托管代码或最坏的情况,炮轰并执行GS命令行,也就是说,我们目前在我们的一个Web应用程序中执行此操作并且运行良好 . 顺便说一句,我们不是为了打印而是为了加入许多PDF文件,但最终它的工作原理是相同的 .
PrintDocument文档包含从C#打印的详细示例 . 打印机名称应指向本地打印机或打印机共享 . 有关打印PDF文档的信息,请参见printing-to-a-pdf-printer-programatically .
有些东西必须将您的Word和PDF文档翻译成打印机能够理解的内容 . 通常情况下,这将是前者的Word本身,以及后者的某种PDF查看器 . 然后需要指示那些程序将输出发送到哪台打印机 .
一种可能的方法是将文档保存为Postscript文件 . 然后可以直接从C#应用程序将它们发送到支持Postscript的打印机 . 这可能是最简单的方法 .
检查sql报告服务的功能可能值5分钟 . 我过去曾用它来直接渲染pdf .
http://blogs.msdn.com/bryanke/articles/71491.aspx
如果窗口已知有问题的文档类型(应该是DOC和PDF),您可以使用Windows动词来执行此操作吗?
Codeproject PDF example : Automated PDF Conversion using the PDF995 and FreePDF_XP Freeware Printers MSDN : Verbs and File Associations
此代码完美运行它使用Adobe阅读器本身进行打印
使用提示1-不要忘记为adobe reader提供自己的安装路径2-从要打印的打印机属性中获取打印机名称
使用这样的类:
而且课程是: