从控制台应用程序上它应该能正常工作。但是,Windows服务或者ASP.NET并不那么容易。
这里有一些建议在这里,但不是很容易(比如使用P/Invoke调用C++库来打印,这是我的第一个想法)。你可以搜索一下看看是否有人已经完成了这个任务。
这个答案推荐了一个第三方产品:DevExpress的XtraReports。
Reddit 上也有这个人描述了他是如何解决这个问题的。你可以给他发送消息并看是否能获得他的代码。
这个例子使用Microsoft.Office.Interop.Word
来从Windows服务中打印Word文档。看起来有些“hacky”,但我不认为它不能正常工作:
public class WordPrintTask
{
private static object locker = new Object();
public WordPrintTask() { }
public void PrintWord()
{
try
{
if (KillProcess("WINWORD"))
{
lock (locker)
{
string fileName = "D:\\PrinterDocs\\TEST.docx";
string printerName = "\\\\10.0.0.89\\PRINTER1020";
if (File.Exists(fileName))
{
Application _application = new Application();
_application.Application.ActivePrinter = printerName;
object oSourceFilePath = (object)fileName;
object docType = WdDocumentType.wdTypeDocument;
object oFalse = (object)false;
object oMissing = System.Reflection.Missing.Value;
Document _document = _application.Documents.Open(ref oSourceFilePath,
ref docType,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing,
ref oMissing);
_application.PrintOut(ref oFalse, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
object saveOptions = WdSaveOptions.wdDoNotSaveChanges;
_document.Close(ref oFalse, ref oMissing, ref oMissing);
if (_application != null)
{
object oSave = false;
Object oMiss = System.Reflection.Missing.Value;
_application.Quit(ref oSave, ref oMiss, ref oMissing);
_application = null;
}
File.Delete(fileName);
}
}
}
}
catch (Exception ex)
{
KillProcess("WINWORD");
}
finally
{
}
}
private static bool KillProcess(string name)
{
foreach (Process clsProcess in Process.GetProcesses().Where(p => p.ProcessName.Contains(name)))
{
if (Process.GetCurrentProcess().Id == clsProcess.Id)
continue;
if (clsProcess.ProcessName.Contains(name))
{
clsProcess.Kill();
return true;
}
}
return true;
}
}