2016-09-29 8 views
0

Java-App에서 MS-Word 템플릿으로 새 문서를 열고 싶지만 템플릿 자체 만 편집하면됩니다.템플릿에서 새 문서 만들기

내 상황은 다음과 같습니다. 내 Jar 파일 내부는 단어 템플릿이며 사용자가 지정한 위치로 복사되어 편집 할 수 있습니다. 그런 다음 응용 프로그램은이 편집 된 템플릿을 열고 데이터를 삽입 한 다음 단어로 열 수 있습니다. 이 모든 것은 잘 작동하지만 (Apache-POI 사용), 마지막 단계는 내가 원하는 것만은 아니다.

일반적으로 단어 서식 파일을 두 번 클릭하면 Word에서 아무데도 저장되지 않은 새 문서 (문서 1)가 열립니다. 필자의 경우, Word는 편집을위한 단어 템플릿 (blablaMyTemplate이라는 제목)을 엽니 다. 즉, 문서를 만들어야하는 이미 저장 한 템플릿을 의미합니다. Java를 사용하여 템플릿에서 새로 생성 된 문서를 어떻게 열 수 있습니까?

이것은 (생략 시도/캐치 스트림 폐쇄) 내 코드입니다 :

File bbb = new File(new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile().getParentFile().getAbsolutePath() + "/blablaMyTemplate.dotx"); 
    if (!bbb.exists()) { //copy file to outside of jar for user editing 
     Files.copy(Buchungsbegleitblatt.class.getResourceAsStream("bbb.dotx"), bbb.toPath(), StandardCopyOption.REPLACE_EXISTING); 
    } 
    File tmp = File.createTempFile("bbb", ".dotx"); //create tmp file to insert data 
    InputStream in = new FileInputStream(bbb); 
    OutputStream out = new FileOutputStream(tmp); 
    XWPFDocument document = new XWPFDocument(in); 
    //here, some data is filled into the document using Apache-POI (omitted, because it works fine) 
    document.write(out); 
    if (Desktop.isDesktopSupported()) { 
     Desktop.getDesktop().open(tmp); //this opens the template for editing, it does not create a new doc from template 
    } 

문제는 마지막 줄 내에있는,하지만 난 여기 부를 수있는 그 밖의 무엇을 모른다. 이 작업을 수행하는

context menu on template

답변

2

정확하게 문제를 이미 설명했습니다. Desktop.open 정확히 말한대로 할 것입니다. 파일 유형에 지정된 호출 된 응용 프로그램에 대해 open 이벤트를 수행합니다.

new 이벤트를 수행하면됩니다. 이것은 Word에서 startup command-line switches to start Word을 사용하여 달성 할 수 있습니다. 링크 된 지식 기반 항목에서

찾을 수 있습니다

...

/ttemplate_name Starts Word with a new document based on a template other than the Normal template.

...

수행 작업을 너무와 Java 중 하나 Runtime.getRuntime().exec 또는 ProcessBuilder 사용할 수 있습니다. 둘 다 먼저 명령 인터프리터 CMD을 셸로 시작하고이 응용 프로그램을 시작하기 위해 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 "" "The name of the file.ext"

예 :

start "" "The name of the file.dotx"

start 명령은 우리가 응용 프로그램 이름으로 빈 문자열 "" 줄 경우, 지정된 파일을 파일 확장자에 따라 기본 동작을 수행 할 수있는 기능이 있습니다

레지스트리 데이터베이스의 dotx 확장명과 관련된 응용 프로그램의 응용 프로그램에서 기본 동작을 수행합니다.

그래서 :

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(); 
     } 
    } 
} 
+0

정말 고마워요! 난 그냥 약간의 후속 질문 : winword.exe 실제로 존재하는 경우 검색 방법이 있습니까? 그렇지 않으면 오류가 분명히 발생합니다 ("windord.exe를 찾을 수 없습니다"등). 그러나 프로세스에서 생성 할 수있는 오류 (예 : 액세스 거부)에 대해 '1'을 반환하므로 나는 단지 그것에 갈 수 없어 ... – user2336377

+0

목표는 무엇입니까? Windows 오류 메시지 방지? 이것은 불가능합니다. 이를 위해 우리는 ** 시작하기 전에 ** 응용 프로그램이 설치되어 있는지 여부에 관계없이 전체 Windows 시스템을 검사해야합니다. 그렇지 않으면,'ProcessBuilder'는 에러 스트림을 출력 스트림과 함께 파일로 리디렉션 할 수 있습니다. 또는'process.getErrorStream();'을 사용하여'Process'에서 Error 스트림을 가져 와서 이것을 읽을 수 있습니다. –

+0

목표는 다음과 같습니다. MSWord가 올바르게 설치되어 있는지 확인하고, 그렇다면'ProcessBuilder'를 사용하여 템플릿에서 새 문서를 시작합니다. 그렇지 않으면 템플릿에서 임시 폴더에 저장된 문서를 만들고 정기적으로'Desktop.open (...)'(예를 들어, LibreOffice를 사용하거나, 사용자가 설치 한 것을 사용)을 사용합니다. 저는 약간 놀아서'process.getErrorStream();'으로 관리 할 수있는 것을 보겠습니다. 도와 줘서 고마워. – user2336377

0

한 가지 방법을을 시작하는 것입니다 :

는 여기에 내가 템플릿 파일을받을 상황에 맞는 메뉴의 이미지입니다 무슨 일이 일어날 것으로 예상되는, 조금 명확하게하려면 Windows에서 여는 내용을 처리하고 기본 의도를 사용하도록 템플릿에서 처리합니다. 자바를 만진 지 꽤 오래되었지만, C#과 같은 것이라면 new Process(tmp).Start()과 같을 것입니다.

비록 이것이 정확히 당신이 찾고있는 것인지 모르겠습니다.

+0

그게 정확히 마지막 줄은 무엇을 ... 그것은 지정된 파일을 열 수 (이 경우 Windows의) 기본 OS를 호출합니다. 자세한 내용은 https://docs.oracle.com/javase/8/docs/api/java/awt/Desktop.html#open-java.io.File- – user2336377

+0

을 참조하십시오. 그것은 또한 의도 부분을 건너 뛸 수있는 것과 같은 종류의 소리입니다. '공정'을 시도해 볼 가치가있다. – Chris

+0

나는 C#으로 많은 일을 해본 적이 없지만 Java 'Process'가 C# 1과 동일하다고 생각하지 않습니다. 적어도 파일을 전달하고 명시한 것처럼 시작하는 방법에 대해 잘 모릅니다. ^^ – user2336377

관련 문제