正确答案是(即):
xlApp.ActivePrinter = "\\\\RR-PS1\\CORPPRT58-Copier Room on Ne00:"
重要的一部分是'Ne00:': 这是打印机所在的端口。它在每台计算机上都不同,并且可以在注册表中找到,路径为HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices
。
另一个问题是连接字符串'on'。当使用英文Excel时这可能是有效的,但在其他语言环境下需要进行翻译处理!
我也遇到了同样的问题,但我找不到太多完整的示例,所以现在提供我的示例:
var path = @"c:\path\to\my\doc.xlsx";
Microsoft.Office.Interop.Excel.Application _xlApp;
Microsoft.Office.Interop.Excel.Workbook _xlBook;
_xlApp = new Microsoft.Office.Interop.Excel.Application();
_xlBook = _xlApp.Workbooks.Open(path);
_xlBook.Activate();
var printer = @"EPSON LQ-690 ESC/P2";
var port = String.Empty;
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(path))
{
if (key != null)
{
object value = key.GetValue(printer);
if (value != null)
{
string[] values = value.ToString().Split(',');
if (values.Length >= 2) port = values[1];
}
}
}
if (!_xlApp.ActivePrinter.StartsWith(printer))
{
var split = _xlApp.ActivePrinter.Split(' ');
if (split.Length >= 3)
{
_xlApp.ActivePrinter = String.Format("{0} {1} {2}",
printer,
split[split.Length - 2],
port);
}
}
_xlBook.PrintOutEx();
我并不知道其他的翻译,所以这个翻译可能还不够完美。如果把'on'翻译成空格,上面的代码就会失败。但是我猜这个解决方法对大多数客户都有效。你可以通过查看ActivePrinter的当前值轻松获取当前连接字符串。
一个更加可靠的方法是去掉打印机名称和指定端口,剩下的就是连接字符串。但是这样你需要循环所有已安装的打印机并检查是否匹配。
另外一个我个人常用的测试是检查此打印机是否在系统中已安装:
if(PrinterSettings.InstalledPrinters.Cast<string>().ToList().Contains(printer)) {
//Set active printer...
}