直接用 swriter 打开一个 libreoffice 邮件合并文本文档

Open a libreoffice mail merged textdocument directly with swriter

我需要帮助直接在新的编写器文档中打开邮件合并操作的结果。

    Object mailMergeService = mcf.createInstanceWithContext(mailMergePackage, context);
    XPropertySet mmProperties = UnoRuntime.queryInterface(XPropertySet.class, mailMergeService);
    mmProperties.setPropertyValue("DocumentURL", templatePath);
    mmProperties.setPropertyValue("DataSourceName", dbName);
    mmProperties.setPropertyValue("CommandType", mmCommandType);
    mmProperties.setPropertyValue("Command", mmCommand);
    mmProperties.setPropertyValue("OutputType", mmOutputType);
    // mmProperties.setPropertyValue("OutputURL", templateDirectory);
    // mmProperties.setPropertyValue("FileNamePrefix", mmFileNamePrefix);
    // mmProperties.setPropertyValue("SaveAsSingleFile", mmSaveAsSingleFile);

mmOutputType 设置为 MailMergeType.SHELL LibreOffice API 文档说

"输出是文档shell。 成功的邮件合并 returns 基于 XTextDocument 的组件。"

所以我试过这样的东西

    XJob job = UnoRuntime.queryInterface(XJob.class, mailMergeService);
    Object mergedTextObject = job.execute(new NamedValue[0]);

    String url = "private:factory/swriter";
    loader.loadComponentFromURL(url, "_blank", 0, new PropertyValue[0]);

    XTextDocument mergedText = UnoRuntime.queryInterface(XTextDocument.class, mergedTextObject);
    XTextCursor cursor = mergedText.getText().createTextCursor();
    cursor.setString(mergedText.getText().getString());

我想我必须将 XTextDocument 组件传递给 loadComponentFromURL 方法的 url 参数,但我没有找到正确的方法。

当我将 OutputType 更改为 MailMergeType.FILE 时,结果在给定目录中生成,我可以打开文件并看到邮件合并成功。但这不是我的应用程序应该做的。

有人知道如何在新的编写器文档中直接打开邮件合并的结果而不将结果保存到硬盘吗?

真诚的亚瑟

您使用的是哪个版本的 LO? SHELL constant has only been around since LO 4.4, and it is not supported by Apache OpenOffice yet, so it could be that it isn't fully implemented. However this code 似乎显示了一个有效的测试。

如果它是 returning 一个 XTextDocument,那么通常我会假设该组件已经打开。但是,听起来您没有看到 Writer window 出现。您是否以无头模式启动 LO?如果没有,那么该过程可能需要几秒钟才能显示。

Object mergedTextObject = job.execute(new NamedValue[0]);
Thread.sleep(10000);

无论如何,在我看来,您的代码似乎有错误。这两行只是将文本插入自身:

XTextCursor cursor = mergedText.getText().createTextCursor();
cursor.setString(mergedText.getText().getString());

可能你打算改为这样写:

XTextDocument mergedText = UnoRuntime.queryInterface(XTextDocument.class, mergedTextObject);

String url = "private:factory/swriter";
XComponent xComponent = loader.loadComponentFromURL(url, "_blank", 0, new PropertyValue[0]);
XTextDocument xTextDocument = (XTextDocument)UnoRuntime.queryInterface(XTextDocument.class, xComponent);
XText xText = (XText)xTextDocument.getText();
XTextRange xTextRange = xText.getEnd();
xTextRange.setString(mergedText.getText().getString());

再想一想:如果整个文档都在 table 中,getString() 可能只是 return 一个空字符串。如果是这种情况,那么您可以使用查看光标或枚举文本内容。

编辑:

要保留包括 table 在内的格式,您可以这样做(改编自 https://blog.oio.de/2010/10/27/copy-and-paste-without-clipboard-using-openoffice-org-api/):

// Select all.
XController xMergedTextController = mergedText.getCurrentController();
XTextViewCursorSupplier supTextViewCursor =
            (XTextViewCursorSupplier) UnoRuntime.queryInterface(
                XTextViewCursorSupplier.class, xMergedTextController);
XTextViewCursor oVC = supTextViewCursor.getViewCursor();
oVC.gotoStart(False)  // This would not work if your document began with a table.
oVC.gotoEnd(True)
// Copy and paste.
XTransferableSupplier xTransferableSupplier = UnoRuntime.queryInterface(XTransferableSupplier.class, xMergedTextController);
XTransferable transferable = xTransferableSupplier.getTransferable();
XController xController = xComponent.getCurrentController();
XTransferableSupplier xTransferableSupplier_newDoc = UnoRuntime.queryInterface(XTransferableSupplier.class, xController);
xTransferableSupplier_newDoc.insertTransferable(transferable);

大家好,我找到了一种直接打开邮件合并过程结果的简单方法。

相关的片段是这些

  XJob job = UnoRuntime.queryInterface(XJob.class, mailMergeService);
  Object mergedTextObject = job.execute(new NamedValue[0]);
  XTextDocument mergedText = UnoRuntime.queryInterface(XTextDocument.class, mergedTextObject);
  mergedText.getCurrentController().getFrame().getContainerWindow().setVisible(true);

最后一行代码使 window 与填充的邮件合并结果一起出现。

我也不需要这条线了

loader.loadComponentFromURL("private:factory/swriter", "_blank", 0, new PropertyValue[0]);

文档作为 swriter 文档的新实例打开。如果你想将结果保存为文件,你可以这样做

  mergedText.getCurrentController().getFrame().getContainerWindow().setVisible(true);
  XStorable storeMM = UnoRuntime.queryInterface(XStorable.class, mergedText);
  XModel modelMM = UnoRuntime.queryInterface(XModel.class, mergedText);
  storeMM.storeAsURL(outputDirectory + outputFilename, modelMM.getArgs());

此致 亚瑟