java如何打开word文档_如何在Java中打开和操作Word文档/模板?

我知道自从我发布这个问题以来已经很长时间了,我说我会在完成后发布我的解决方案.

所以在这里.

我希望有一天它会帮助某人.

这是一个完整的工作类,您只需将它放在应用程序中,并将TEMPLATE_DIRECTORY_ROOT目录与.docx模板放在根目录中.

用法很简单.

您将占位符(键)放在.docx文件中,然后传递文件名和包含该文件的相应键值对的Map.

请享用!

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.BufferedReader;

import java.io.Closeable;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.net.URI;

import java.util.Deque;

import java.util.Enumeration;

import java.util.HashMap;

import java.util.Iterator;

import java.util.LinkedList;

import java.util.Map;

import java.util.UUID;

import java.util.zip.ZipEntry;

import java.util.zip.ZipFile;

import java.util.zip.ZipOutputStream;

import javax.faces.context.ExternalContext;

import javax.faces.context.FacesContext;

import javax.servlet.http.HttpServletResponse;

public class DocxManipulator {

private static final String MAIN_DOCUMENT_PATH = "word/document.xml";

private static final String TEMPLATE_DIRECTORY_ROOT = "TEMPLATES_DIRECTORY/";

/* PUBLIC METHODS */

/**

* Generates .docx document from given template and the substitution data

*

* @param templateName

* Template data

* @param substitutionData

* Hash map with the set of key-value pairs that represent

* substitution data

* @return

*/

public static Boolean generateAndSendDocx(String templateName, Map substitutionData) {

String templateLocation = TEMPLATE_DIRECTORY_ROOT + templateName;

String userTempDir = UUID.randomUUID().toString();

userTempDir = TEMPLATE_DIRECTORY_ROOT + userTempDir + "/";

try {

// Unzip .docx file

unzip(new File(templateLocation), new File(userTempDir));

// Change data

changeData(new File(userTempDir + MAIN_DOCUMENT_PATH), substitutionData);

// Rezip .docx file

zip(new File(userTempDir), new File(userTempDir + templateName));

// Send HTTP response

sendDOCXResponse(new File(userTempDir + templateName), templateName);

// Clean temp data

deleteTempData(new File(userTempDir));

}

catch (IOException ioe) {

System.out.println(ioe.getMessage());

return false;

}

return true;

}

/* PRIVATE METHODS */

/**

* Unzipps specified ZIP file to specified directory

*

* @param zipfile

* Source ZIP file

* @param directory

* Destination directory

* @throws IOException

*/

private static void unzip(File zipfile, File directory) throws IOException {

ZipFile zfile = new ZipFile(zipfile);

Enumeration extends ZipEntry> entries = zfile.entries();

while (entries.hasMoreElements()) {

ZipEntry entry = entries.nextElement();

File file = new File(directory, entry.getName());

if (entry.isDirectory()) {

file.mkdirs();

}

else {

file.getParentFile().mkdirs();

InputStream in = zfile.getInputStream(entry);

try {

copy(in, file);

}

finally {

in.close();

}

}

}

}

/**

* Substitutes keys found in target file with corresponding data

*

* @param targetFile

* Target file

* @param substitutionData

* Map of key-value pairs of data

* @throws IOException

*/

@SuppressWarnings({ "unchecked", "rawtypes" })

private static void changeData(File targetFile, Map substitutionData) throws IOException{

BufferedReader br = null;

String docxTemplate = "";

try {

br = new BufferedReader(new InputStreamReader(new FileInputStream(targetFile), "UTF-8"));

String temp;

while( (temp = br.readLine()) != null)

docxTemplate = docxTemplate + temp;

br.close();

targetFile.delete();

}

catch (IOException e) {

br.close();

throw e;

}

Iterator substitutionDataIterator = substitutionData.entrySet().iterator();

while(substitutionDataIterator.hasNext()){

Map.Entry pair = (Map.Entry)substitutionDataIterator.next();

if(docxTemplate.contains(pair.getKey())){

if(pair.getValue() != null)

docxTemplate = docxTemplate.replace(pair.getKey(), pair.getValue());

else

docxTemplate = docxTemplate.replace(pair.getKey(), "NEDOSTAJE");

}

}

FileOutputStream fos = null;

try{

fos = new FileOutputStream(targetFile);

fos.write(docxTemplate.getBytes("UTF-8"));

fos.close();

}

catch (IOException e) {

fos.close();

throw e;

}

}

/**

* Zipps specified directory and all its subdirectories

*

* @param directory

* Specified directory

* @param zipfile

* Output ZIP file name

* @throws IOException

*/

private static void zip(File directory, File zipfile) throws IOException {

URI base = directory.toURI();

Deque queue = new LinkedList();

queue.push(directory);

OutputStream out = new FileOutputStream(zipfile);

Closeable res = out;

try {

ZipOutputStream zout = new ZipOutputStream(out);

res = zout;

while (!queue.isEmpty()) {

directory = queue.pop();

for (File kid : directory.listFiles()) {

String name = base.relativize(kid.toURI()).getPath();

if (kid.isDirectory()) {

queue.push(kid);

name = name.endsWith("/") ? name : name + "/";

zout.putNextEntry(new ZipEntry(name));

}

else {

if(kid.getName().contains(".docx"))

continue;

zout.putNextEntry(new ZipEntry(name));

copy(kid, zout);

zout.closeEntry();

}

}

}

}

finally {

res.close();

}

}

/**

* Sends HTTP Response containing .docx file to Client

*

* @param generatedFile

* Path to generated .docx file

* @param fileName

* File name of generated file that is being presented to user

* @throws IOException

*/

private static void sendDOCXResponse(File generatedFile, String fileName) throws IOException {

FacesContext facesContext = FacesContext.getCurrentInstance();

ExternalContext externalContext = facesContext.getExternalContext();

HttpServletResponse response = (HttpServletResponse) externalContext

.getResponse();

BufferedInputStream input = null;

BufferedOutputStream output = null;

response.reset();

response.setHeader("Content-Type", "application/msword");

response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

response.setHeader("Content-Length",String.valueOf(generatedFile.length()));

input = new BufferedInputStream(new FileInputStream(generatedFile), 10240);

output = new BufferedOutputStream(response.getOutputStream(), 10240);

byte[] buffer = new byte[10240];

for (int length; (length = input.read(buffer)) > 0;) {

output.write(buffer, 0, length);

}

output.flush();

input.close();

output.close();

// Inform JSF not to proceed with rest of life cycle

facesContext.responseComplete();

}

/**

* Deletes directory and all its subdirectories

*

* @param file

* Specified directory

* @throws IOException

*/

public static void deleteTempData(File file) throws IOException {

if (file.isDirectory()) {

// directory is empty, then delete it

if (file.list().length == 0)

file.delete();

else {

// list all the directory contents

String files[] = file.list();

for (String temp : files) {

// construct the file structure

File fileDelete = new File(file, temp);

// recursive delete

deleteTempData(fileDelete);

}

// check the directory again, if empty then delete it

if (file.list().length == 0)

file.delete();

}

} else {

// if file, then delete it

file.delete();

}

}

private static void copy(InputStream in, OutputStream out) throws IOException {

byte[] buffer = new byte[1024];

while (true) {

int readCount = in.read(buffer);

if (readCount < 0) {

break;

}

out.write(buffer, 0, readCount);

}

}

private static void copy(File file, OutputStream out) throws IOException {

InputStream in = new FileInputStream(file);

try {

copy(in, out);

} finally {

in.close();

}

}

private static void copy(InputStream in, File file) throws IOException {

OutputStream out = new FileOutputStream(file);

try {

copy(in, out);

} finally {

out.close();

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值