Java 从模板创建新文档

Java 从模板创建新文档,java,ms-word,apache-poi,word-template,Java,Ms Word,Apache Poi,Word Template,我想从Java应用程序的MS Word模板中打开一个新文档,但只能编辑模板本身 以下是我的情况: 在我的Jar文件中有一个word模板,它被复制到用户指定的位置,以便他/她可以编辑它。然后,应用程序可以打开此编辑过的模板,将数据插入其中并在word中打开。这一切都很好(使用ApachePOI),但最后一步并不完全是我想要的 通常,双击word模板时,word会打开一个尚未保存在任何位置的新文档(标题为Document1)。在我的例子中,Word打开Word模板进行编辑(标题为BlablamByT

我想从Java应用程序的MS Word模板中打开一个新文档,但只能编辑模板本身

以下是我的情况: 在我的Jar文件中有一个word模板,它被复制到用户指定的位置,以便他/她可以编辑它。然后,应用程序可以打开此编辑过的模板,将数据插入其中并在word中打开。这一切都很好(使用ApachePOI),但最后一步并不完全是我想要的

通常,双击word模板时,word会打开一个尚未保存在任何位置的新文档(标题为Document1)。在我的例子中,Word打开Word模板进行编辑(标题为BlablamByTemplate),这意味着应该从中创建文档的已保存模板。如何使用Java从模板打开新创建的文档

这是我的代码(try/catch和流关闭省略):

问题就在最后一行,但我不知道我在这里还能叫什么

为了让它更清楚一点,下面是我在模板文件上得到的上下文菜单的图像,以及应该发生的事情:


一种方法是在模板上启动一个进程,以便Windows处理打开的操作,并使用默认意图。我已经有一段时间没有接触Java了,但是如果它像C,它将类似于
新进程(tmp).Start()


不过,我不确定这是否正是您想要的。

实现这一点的一种方法是在模板上启动一个流程,以便Windows能够处理打开的部分,并使用默认意图。我已经有一段时间没有接触Java了,但是如果它像C,它将类似于
新进程(tmp).Start()


不过,我不确定这是否正是您想要的。

您已经准确地描述了问题<代码>桌面。打开将完全按照它所说的去做。它将为分配给文件类型的被调用应用程序执行
打开
事件

您需要的是执行
new
事件。这可以通过使用
Word
实现

在链接的知识库条目中,您可以找到:

/t模板\u name以基于模板的新文档开头Word
普通模板以外的模板。

要使用
Java
执行此操作,可以使用
Runtime.getRuntime().exec
ProcessBuilder
。对于这两个命令,我建议首先启动命令解释器
CMD
,作为shell,并在此使用
start
命令启动应用程序。因此,我们不需要知道应用程序的确切路径

示例:

import java.io.*;

class RuntimeExec {
  public static void main(String[] args) {
      try {
        // Execute a command as a single line
        File f = new File("C:/Users/axel/Documents/The Template.dotx");
        System.out.println(f.getAbsolutePath());
        String cmd = "cmd /C start winword.exe /t\"" + f.getAbsolutePath() + "\"";
        Process child = Runtime.getRuntime().exec(cmd);

      } catch (IOException e) {
        e.printStackTrace();
      }

  }
}

class UseProcessBuilder {
  public static void main(String[] args) {
      try {
        //use ProcessBuilder to have more control
        File f = new File("C:/Users/axel/Documents/The Template.dotx");
        System.out.println(f.getAbsolutePath());
        String application = "winword.exe";
        String switchNewFromTemplate = "/t";
        String file = f.getAbsolutePath(); 
        ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "start", application, switchNewFromTemplate+file);
        Process process = pb.start();

      } catch (IOException e) {
        e.printStackTrace();
      }
  }
}

有一种可能是不显式启动
winword
应用程序。如果我们将空字符串
作为应用程序名称,则
start
命令具有根据给定文件的文件扩展名执行默认操作的功能:

start”“”文件名。ext“

例如:

start”““文件名.dotx”

这将在
winword
应用程序中执行与注册表数据库中的
dotx
扩展相关的默认操作
new

因此:


你已经准确地描述了这个问题<代码>桌面。打开将完全按照它所说的去做。它将为分配给文件类型的被调用应用程序执行
打开
事件

您需要的是执行
new
事件。这可以通过使用
Word
实现

在链接的知识库条目中,您可以找到:

/t模板\u name以基于模板的新文档开头Word
普通模板以外的模板。

要使用
Java
执行此操作,可以使用
Runtime.getRuntime().exec
ProcessBuilder
。对于这两个命令,我建议首先启动命令解释器
CMD
,作为shell,并在此使用
start
命令启动应用程序。因此,我们不需要知道应用程序的确切路径

示例:

import java.io.*;

class RuntimeExec {
  public static void main(String[] args) {
      try {
        // Execute a command as a single line
        File f = new File("C:/Users/axel/Documents/The Template.dotx");
        System.out.println(f.getAbsolutePath());
        String cmd = "cmd /C start winword.exe /t\"" + f.getAbsolutePath() + "\"";
        Process child = Runtime.getRuntime().exec(cmd);

      } catch (IOException e) {
        e.printStackTrace();
      }

  }
}

class UseProcessBuilder {
  public static void main(String[] args) {
      try {
        //use ProcessBuilder to have more control
        File f = new File("C:/Users/axel/Documents/The Template.dotx");
        System.out.println(f.getAbsolutePath());
        String application = "winword.exe";
        String switchNewFromTemplate = "/t";
        String file = f.getAbsolutePath(); 
        ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "start", application, switchNewFromTemplate+file);
        Process process = pb.start();

      } catch (IOException e) {
        e.printStackTrace();
      }
  }
}

有一种可能是不显式启动
winword
应用程序。如果我们将空字符串
作为应用程序名称,则
start
命令具有根据给定文件的文件扩展名执行默认操作的功能:

start”“”文件名。ext“

例如:

start”““文件名.dotx”

这将在
winword
应用程序中执行与注册表数据库中的
dotx
扩展相关的默认操作
new

因此:


这正是最后一行所做的。。。它调用本机操作系统(在本例中为Windows)打开指定的文件。看这里:听起来确实是这样。这听起来也有点像是跳过了意图部分。值得尝试
Process
imo。我从来没有对C#做过很多工作,但我认为Java
Process
与C#one不一样。至少我不知道如何将文件传递给它,然后像您所说的那样启动它。^^^这正是最后一行所做的。。。它调用本机操作系统(在本例中为Windows)打开指定的文件。看这里:听起来确实是这样。这听起来也有点像是跳过了意图部分。值得尝试
Process
imo。我从来没有对C#做过很多工作,但我认为Java
Process
与C#one不一样。至少我不知道如何将文件传递给它,然后像您所说的那样启动它。^^^这很有效,非常感谢!我只是有一个小问题:有没有办法检测winword.exe是否确实存在?
class RuntimeExec {
  public static void main(String[] args) {
      try {
        // Execute a command as a single line
        File f = new File("C:/Users/Axel Richter/Documents/The Template.dotx");
        System.out.println(f.getAbsolutePath());
        String cmd = "cmd /C start \"\" \"" + f.getAbsolutePath() + "\"";
        Process child = Runtime.getRuntime().exec(cmd);

        InputStream in = child.getErrorStream();
        int c;
        while ((c = in.read()) != -1) {
            System.out.print((char)c);
        }
        in.close();

      } catch (IOException e) {
        e.printStackTrace();
      }

  }
}

class UseProcessBuilder {
  public static void main(String[] args) {
      try {
        //use ProcessBuilder to have more control
        File f = new File("C:/Users/Axel Richter/Documents/The Template.dotx");
        System.out.println(f.getAbsolutePath());
        String file = f.getAbsolutePath(); 
        ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "start", "\"\"", file);
        Process process = pb.start();

        InputStream in = process.getErrorStream();
        int c;
        while ((c = in.read()) != -1) {
            System.out.print((char)c);
        }
        in.close();

      } catch (IOException e) {
        e.printStackTrace();
      }
  }
}