如何使用 Microsoft.Office.Interop.Word.Document.PrintOut() 将 docx 打印到特定打印机

2024-04-20

这似乎是一个简单的需求,但由于某种原因我找不到如何实现这一点。我有这样的代码:

Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
MemoryStream documentStream = getDocStream();
FileInfo wordFile = new FileInfo("c:\\test.docx");
object fileObject = wordFile.FullName;
object oMissing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Word.Document doc = wordInstance.Documents.Open(ref fileObject, 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);
doc.Activate();
doc.PrintOut(oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);

我需要一个配置设置驱动器来使用打印机和托盘。搜索后,我发现 Microsoft.Office.Interop.Word.Application.ActivePrinter 这是一个可设置的字符串属性,文档说它采用“活动打印机的名称”,但我不知道这对于打印机来说意味着什么“活动打印机”,尤其是当我有两个时。如何才能做到这一点?


TL;DR您无法打印到特定打印机。您必须将默认打印机更改为您想要使用的打印机。然后正常打印。

自从我们第一次在这个领域开展工作以来,情况可能已经发生了巨大的变化,但我们无法找到任何方法来打印到特定的打印机。因此,我们所做的就是将系统的默认打印机更改为我们想要的,在该计算机上打印我们想要的所有文档,然后将其改回之前的状态。 (实际上,我们不再将其更改回来,因为没有其他任何东西需要任何特定的默认打印机,所以这并不重要)。

简短回答:

Microsoft.Office.Interop.Word._Application _app = [some valid COM instance];
Microsoft.Office.Interop.Word.Document doc = _app.Documents.Open(ref fileName, ...);
doc.Application.ActivePrinter = "name of printer";
doc.PrintOut(/* ref options */);

但是,我们发现这非常不可靠!请阅读以获得更多详情:

如果您还没有这样做,我强烈建议您构建自己的包装类来处理所有平凡的工作_Document and _Application。现在可能没有以前那么糟糕了(dynamic对我们来说不是一个选择),但这仍然是一个好主意。您会注意到,其中缺少某些美味的代码......我试图将重点放在与您所要求的内容相关的代码上。还有,这个DocWrapper类是代码中许多独立部分的合并——请原谅这种混乱。最后,如果您认为异常处理很奇怪(或者只是抛出异常而导致设计不佳),请记住我正在尝试将来自许多地方的部分代码组合在一起(同时也忽略了我们自己的自定义类型)。阅读代码中的注释,它们很重要。

class DocWrapper
{
  private const int _exceptionLimit = 4;

  // should be a singleton instance of wrapper for Word
  // the code below assumes this was set beforehand
  // (e.g. from another helper method)
  private static Microsoft.Office.Interop.Word._Application _app;

  public virtual void PrintToSpecificPrinter(string fileName, string printer)
  {
    // Sometimes Word fails, so needs to be restarted.
    // Sometimes it's not Word's fault.
    // Either way, having this in a retry-loop is more robust.
    for (int retry = 0; retry < _exceptionLimit; retry++)
    {
      if (TryOncePrintToSpecificPrinter(fileName, printer))
        break;

      if (retry == _exceptionLimit - 1) // this was our last chance
      {
        // if it didn't have actual exceptions, but was not able to change the printer, we should notify somebody:
        throw new Exception("Failed to change printer.");
      }
    }
  }

  private bool TryOncePrintToSpecificPrinter(string fileName, string printer)
  {
    Microsoft.Office.Interop.Word.Document doc = null;

    try
    {
      doc = OpenDocument(fileName);

      if (!SetActivePrinter(doc, printer))
        return false;

      Print(doc);

      return true; // we did what we wanted to do here
    }
    catch (Exception e)
    {
      if (retry == _exceptionLimit)
      {
        throw new Exception("Word printing failed.", e);
      }
      // restart Word, remembering to keep an appropriate delay between Quit and Start.
      // this should really be handled by wrapper classes
    }
    finally
    {
      if (doc != null)
      {
        // release your doc (COM) object and do whatever other cleanup you need
      }
    }

    return false;
  }

  private void Print(Microsoft.Office.Interop.Word.Document doc)
  {
    // do the actual printing:
    doc.Activate();
    Thread.Sleep(TimeSpan.FromSeconds(1)); // emperical testing found this to be sufficient for our system
    // (a delay may not be required for you if you are printing only one document at a time)
    doc.PrintOut(/* ref objects */);
  }

  private bool SetActivePrinter(Microsoft.Office.Interop.Word.Document doc, string printer)
  {
    string oldPrinter = GetActivePrinter(doc); // save this if you want to preserve the existing "default"

    if (printer == null)
      return false;

    if (oldPrinter != printer)
    {
      // conditionally change the default printer ...
      // we found it inefficient to change the default printer if we don't have to. YMMV.
      doc.Application.ActivePrinter = printer;
      Thread.Sleep(TimeSpan.FromSeconds(5)); // emperical testing found this to be sufficient for our system
      if (GetActivePrinter(doc) != printer)
      {
        // don't quit-and-restart Word, this one actually isn't Word's fault -- just try again
        return false;
      }

      // successful printer switch! (as near as anyone can tell)
    }

    return true;
  }

  private Microsoft.Office.Interop.Word.Document OpenDocument(string fileName)
  {
    return _app.Documents.Open(ref fileName, /* other refs */);
  }

  private string GetActivePrinter(Microsoft.Office.Interop.Word._Document doc)
  {
    string activePrinter = doc.Application.ActivePrinter;
    int onIndex = activePrinter.LastIndexOf(" on ");
    if (onIndex >= 0)
    {
      activePrinter = activePrinter.Substring(0, onIndex);
    }
    return activePrinter;
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Microsoft.Office.Interop.Word.Document.PrintOut() 将 docx 打印到特定打印机 的相关文章

  • 调用许多网络服务的最佳方式?

    我有 30 家子公司 每家都实施了他们的 Web 服务 使用不同的技术 我需要实现一个Web服务来聚合它们 例如 所有子公司的Web服务都有一个名为的Web方法GetUserPoint int nationalCode 我需要实现我的网络服
  • 通过另一个列表更新列表(linq)

    我有类 Data 的对象列表 如下所示 class Data int code string name DateTime date update 我还有另一个课程列表 例如 class RefCodes int old code int n
  • 当其源是 https uri 时如何使 wpf MediaElement 播放

    在 wpf 独立应用程序 exe 中 我在主窗口中包含了 MediaElement
  • 通过 SOAP 的 Gmt php 或 UTC C# 等效项

    is C DateTime UtcNow和 PHPdate c 是等价的 我怀疑 因为当我肥皂时 我得到了 C
  • 从另一个 FORM 中取回隐藏的 FORM

    我有两种形式Form1 and Form2 我正在打开Form2 from Form1 on button Click Form2 obj2 new Form2 this Visible false obj2 Show 然后我想回来Form
  • 使用 Xamarin.Forms 和 Zxing 生成 QR 码

    我在网上看到了很多关于这个的内容 旧帖子 但似乎没有什么对我有用 我正在尝试从字符串中生成二维码并将其显示在应用程序中 这就是我一开始的情况 qrCode new ZXingBarcodeImageView BarcodeFormat Ba
  • .pdbs 会减慢发布应用程序的速度吗?

    如果 dll 中包含 pdb 程序调试 文件 则行号将出现在引发的任何异常的堆栈跟踪中 这会影响应用程序的性能吗 这个问题与发布与调试 即优化 无关 这是关于拥有 pdb 文件的性能影响 每次抛出异常时都会读取 pdb 文件吗 加载程序集时
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • PrivateObject 找不到属性

    我的结构基本上如下所示 abstract class A protected string Identificator get set private void DoSomething DoSomethingSpecific protect
  • “没有合适的默认构造函数可用”——为什么会调用默认构造函数?

    我已经查看了与此相关的其他一些问题 但我不明白为什么在我的情况下甚至应该调用默认构造函数 我可以只提供一个默认构造函数 但我想了解它为什么这样做以及它会产生什么影响 error C2512 CubeGeometry no appropria
  • 如何设置消息队列的所有者?

    System Messaging MessageQueue 类不提供设置队列所有权的方法 如何以编程方式设置 MSMQ 消息队列的所有者 简短的答案是 p invoke 对 windows api 函数的调用MQSetQueueSecuri
  • 编写具有多种类型的泛型扩展方法时的类型推断问题

    我正在为 IEnumerable 编写一个通用扩展方法 用于将对象列表映射到另一个映射对象列表 这就是我希望该方法的工作方式 IList
  • 从点云检测平面集

    我有一组点云 我想测试3D房间中是否有角落 所以我想讨论一下我的方法 以及在速度方面是否有更好的方法 因为我想在手机上测试它 我将尝试使用霍夫变换来检测线 然后我将尝试查看是否有三条线相交 并且它们也形成了两个相交的平面 如果点云数据来自深
  • 如果在代码中添加元素,“FindName”将不起作用

    在 WPF 应用程序中 如果在 XAML 中声明 ContentControl
  • 在 C++ 代码 gdb 中回溯指针

    我在运行 C 应用程序时遇到段错误 在 gdb 中 它显示我的一个指针位置已损坏 但我在应用程序期间创建了 10 万个这样的对象指针 我怎样才能看到导致崩溃的一个 我可以在 bt 命令中执行任何操作来查看该指针的生命周期吗 谢谢 鲁奇 据我
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 时间:2019-03-17 标签:c#TimerStopConfusion

    我想通过单击按钮时更改文本颜色来将文本框文本设置为 闪烁 我可以让文本按照我想要的方式闪烁 但我希望它在闪烁几次后停止 我不知道如何在计时器触发几次后让它停止 这是我的代码 public Form1 InitializeComponent
  • 在二进制数据文件的标头中放入什么

    我有一个模拟 可以读取我们创建的大型二进制数据文件 10 到 100 GB 出于速度原因 我们使用二进制 这些文件依赖于系统 是从我们运行的每个系统上的文本文件转换而来的 所以我不关心可移植性 当前的文件是 POD 结构的许多实例 使用 f
  • 在 C 中使用 #define 没有任何价值

    If a define没有任何价值地使用 例如 define COMMAND SPI 默认值是0吗 不 它的评估结果为零 从字面上看 该符号被替换为空 然而 一旦你有了 define FOO 预处理器条件 ifdef FOO现在将是真的 另
  • MSVC编译器下使用最大成员初始化联合

    我正在尝试初始化一个LARGE INTEGER在 C 库中为 0 确切地说是 C 03 以前 初始化是 static LARGE INTEGER freq 0 在 MinGW 下它产生了一个警告 缺少成员 LARGE INTEGER Hig

随机推荐

  • 单个 DLL V 多个 DLL

    前段时间我在这里问了一个问题 当时我想知道是否最好将一个大项目 NET 类库 拆分为多个 NET DLL 建议使用一个大的 DLL 该 DLL 现在已在另一个项目中使用 另一个项目只使用了几个类 因此项目中有很多类未使用 从体系结构的角度来
  • 你能在条件表达式中添加条件表达式吗? (是:边界检查如何扩展到多个维度?)

    Note 我通过实现一个完全不同的问题来解决最初的问题 有关新的实际问题 请参阅附录 但您可以阅读前一部分以了解上下文 这是我的一个的扩展以前的帖子 https stackoverflow com q 10171525 1010226 我根
  • Webpack 用于后端?

    我只是想知道 我开始在一个新项目中使用 Webpack 到目前为止它运行良好 我几乎可以说我比我之前用过的 Grunt 更喜欢它 但现在我很困惑如何和 或应该将它与我的 Express 后端一起使用 看 我正在创建一个具有前端 ReactJ
  • 如何实现“ui-sref”有条件执行?

    我想在浏览器遵循 ui router 动态创建的链接之前验证某些条件 我正在调查 rootscope on stateChangeStart 但我无法访问controller scope从那里 我还需要在应用程序的几个地方使用它 这会很麻烦
  • 无法使 ExposeDropdownMenu 与 OutlinedTextField 宽度相同

    我遇到以下问题 下拉菜单项的宽度与 OutlinedTextField 的宽度不同 寻找解决方案 发现以下内容 添加要保留的变量textField width var textFieldSize by remember mutableSta
  • NoClassDefFound ShortTypeHandling 与 gradle 自定义插件使用

    我写了一些常规代码 使用编译compile localGroovy 并将 jar 发布到artificialy 现在我写了一个gradle插件 其中有compile localGroovy and compile gav of jar ab
  • 为什么我不能将 Clojure 的 :^const 与 Java 字节数组一起使用?

    Using lein repl使用 Clojure 1 4 0 我可以定义一个 constJava 字节数组的 但我不能用它做任何事情 user gt def x byte array map byte 0 1 2 3 user x use
  • React.js 错误“相邻 JSX 元素必须包含在封闭标记中”

    我有下面的代码是react js 它抛出一个错误 相邻的 JSX 元素必须包含在封闭标签中 看起来 React 不接受彼此相邻的相同标签 如何显示表格数据 var TestRecords React createClass render f
  • SetThreadName 不适用于 Visual Studio 2005

    设置线程名称 http msdn microsoft com en us library xcb2z8hs 28v VS 71 29 aspx当使用 Visual Studio 2005 时 不会设置线程名称 如下所示 DWORD thre
  • Qt 不支持 Visual Studio 的 Unicode 或字体错误

    我是初学者 现在我正在学习 Qt 并使用 Visual Studio 扩展 Qt VS Tool 2 4 3 我使用的文本是越南语 当我构建程序时 它很好 但按钮显示特殊字符 我已经阅读了一些有关字体错误的主题 但它与此错误无关 我的代码
  • 提交简单的表单并捕获屏幕前后

    我正在尝试使用 phantomjs 提交一个简单的表单 这是我的代码 var webPage require webpage var page webPage create page settings userAgent Mozilla 5
  • 如何获取属性名称而不是变量中的 slug?

    我需要从 woocommerce 产品变体中获取属性 terms get post meta value variation id attribute pa color true 这段代码给了我一个属性而不是名称 如何获取属性名称 提前非常
  • 在 Markdown 中围绕文本浮动图形和标题以进行 html 输出

    我正在尝试使用 knitr 构建一个 html 报告 其中有文本描述 并混合了一些图形 如果可能的话 我希望能够将图形浮动到一边 并在未使用的空间中包含文本 我是其中的一部分 但我的问题是图形标题现在与图形本身分离 例如 请参见下图 这是可
  • Netezza 使用 SSIS 从 Sql 服务器增量加载

    我正在尝试使用 SSIS 从 Sql server 2008 到 Netezza Nps6 进行增量加载 使用 Netezza 5 x 版本 OLEDB 驱动程序 我在用Table or View Fast Load选项与Maximum i
  • Pygame 中每次点击都会触发两次跳转

    你好 我目前正在尝试在 pygame 中制作一个跳跃游戏 很像 chrome 恐龙游戏 我编写了一些简单的代码来绘制一个正方形并使其跳跃 我将我的代码写在下面 我的问题是跳跃部分 每当我按下w 即跳跃按钮 时 方块就会跳跃多次 通常是2次
  • 最新安全更新后无法打印图像

    我的申请在之后无法打印最新的安全更新 https www windowscentral com microsoft confirms crashes caused latest windows 10 update 所有 API 调用都不会失
  • scala:Any 和 AnyRef 有什么区别? [复制]

    这个问题在这里已经有答案了 只是好奇类型之间的区别Any and AnyRef在斯卡拉 为什么int属于AnyVal但字符串属于AnyRef 例如 val a AnyVal 3 val b AnyRef 1 Any 是所有类型的超类型 An
  • 仅返回存储过程的最后一个选择结果

    要求表示 存储过程用于根据 5 个标识符搜索数据 如果存在精确匹配 则仅返回精确匹配 如果没有 但非空参数上存在精确匹配 则仅返回这些结果 否则返回任何 4 个非空参数上的任何匹配 等等 我的 简化的 代码如下所示 create proce
  • 如何提高图像的DPI并使其更清晰?

    我想将图像分辨率提高到 300 dpi 而且我有一个不可读的文本图像 所以我想缩放其文字大小和清晰度 我怎样才能做到这一点 从初学者开始 如果你有一张模糊的图像 你就无法取消它的模糊 信息已经丢失了 提高现有图像的图像分辨率也无法添加信息
  • 如何使用 Microsoft.Office.Interop.Word.Document.PrintOut() 将 docx 打印到特定打印机

    这似乎是一个简单的需求 但由于某种原因我找不到如何实现这一点 我有这样的代码 Microsoft Office Interop Word Application word new Microsoft Office Interop Word