您的位置:首页 > Web前端 > CSS

java生成带有样式、表格、不定图片的word

2016-08-06 10:50 501 查看

java生成带有样式、表格、不定图片的word

主要用的技术:

freemark

poi

jacob

简述

现在项目有个需求,要根据选择的内容生成word文档,文档本身带样式,里面有表

格,根据选择的内容图片数量也不定。本人研究的比较浅显,以下所述也只代表个人

观点。poi操作word有两个方面:一、操作word文档,读写,生成word的话用的是

poi规定的一些方法,这种情况下要根据要求生成表格比较麻烦,即使能生成word,

但要生成带一定样式的word也比较费劲;二、可以word文档里面自己做的标记替

换成想要的内容,如将content替换成一段描述,这个替换也可以是图片。

freemark生成word,将word转存成xml,再将xml后缀名直接修改成ftl,然后就像

平常用freemark一样,最后生成word即可(这块网上示例较多,不做啰嗦)。

freemark也可以替换word里面的图片,但不灵活。jacob,本身对word可做的事可

能很多,但这里我只用到了替换图片。本来想的是,将需求方给出的word模板,制

作成ftl模板,利用freemark替换内容生成word,所有该放图片的地方,放入特定标

签(如${iamge1}),再用poi将特定标签换成图片,但最后发现poi打不开第三方生

成的word文档,只好将替换图片这一步换成用jacob来做,下面给出源码。

frmmark生成word

自己百度

poi替换图片

注意:这套代码只适用于word 2007,并且 poi 版本 3.7

maven依赖

<dependency>

<groupId>org.apache.poi</groupId>

<artifactId>poi</artifactId>

<version>3.7</version>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>org.apache.poi</groupId>

<artifactId>poi-ooxml</artifactId>

<version>3.7</version>

</dependency>

<dependency>

<groupId>org.apache.poi</groupId>

<artifactId>poi-ooxml-schemas</artifactId>

<version>3.7</version>

</dependency>


/**
* 适用于word 2007
* poi 版本 3.7
*/
public class WordUtil {
/**
* 根据指定的参数值、模板,生成 word 文档
* @param param 需要替换的变量
* @param template 模板
*/
public static CustomXWPFDocument generateWord(Map<String, Object> param, String template) {
CustomXWPFDocument doc = null;

try {
OPCPackage pack = POIXMLDocument.openPackage(template);
/*
//HWPFDocument doc = null;
FileInputStream in=new FileInputStream(new File(template));
doc=new HWPFDocument(in);*/
doc = new CustomXWPFDocument(pack);
if (param != null && param.size() > 0) {

//处理段落
List<XWPFParagraph> paragraphList = doc.getParagraphs();
processParagraphs(paragraphList, param, doc);

//处理表格
Iterator<XWPFTable> it = doc.getTablesIterator();
while (it.hasNext()) {
XWPFTable table = it.next();
List<XWPFTableRow> rows = table.getRows();
for (XWPFTableRow row : rows) {
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
List<XWPFParagraph> paragraphListTable =  cell.getParagraphs();
processParagraphs(paragraphListTable, param, doc);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return doc;
}
/**
* 处理段落
* @param paragraphList
*/
public static void processParagraphs(List<XWPFParagraph>   paragraphList,Map<String, Object> param,CustomXWPFDocument doc){
if(paragraphList != null && paragraphList.size() > 0){
for(XWPFParagraph paragraph:paragraphList){
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
String text = run.getText(0);
if(text != null){
boolean isSetText = false;
for (Map.Entry<String, Object> entry : param.entrySet()) {
String key = entry.getKey();
if(text.indexOf(key) != -1){
isSetText = true;
Object value = entry.getValue();
if (value instanceof String) {//文本替换
text = text.replace(key, value.toString());
} else if (value instanceof Map) {//图片替换
text = text.replace(key, "");
Map pic = (Map)value;
int width = Integer.parseInt(pic.get("width").toString());
int height = Integer.parseInt(pic.get("height").toString());
int picType = getPictureType(pic.get("type").toString());
byte[] byteArray = (byte[]) pic.get("content");
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);
try {
int ind =doc.addPicture(byteInputStream, picType);
doc.createPicture(ind, width , height,paragraph);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
if(isSetText){
run.setText(text,0);
}
}
}
}
}
}
/**
* 根据图片类型,取得对应的图片类型代码
* @param picType
* @return int
*/
private static int getPictureType(String picType){
int res = CustomXWPFDocument.PICTURE_TYPE_PICT;
if(picType != null){
if(picType.equalsIgnoreCase("png")){
res = CustomXWPFDocument.PICTURE_TYPE_PNG;
}else if(picType.equalsIgnoreCase("dib")){
res = CustomXWPFDocument.PICTURE_TYPE_DIB;
}else if(picType.equalsIgnoreCase("emf")){
res = CustomXWPFDocument.PICTURE_TYPE_EMF;
}else if(picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")){
res = CustomXWPFDocument.PICTURE_TYPE_JPEG;
}else if(picType.equalsIgnoreCase("wmf")){
res = CustomXWPFDocument.PICTURE_TYPE_WMF;
}
}
return res;
}
/**
* 将输入流中的数据写入字节数组
* @param in
* @return
*/
public static byte[] inputStream2ByteArray(InputStream in,boolean isClose){
byte[] byteArray = null;
try {
int total = in.available();
byteArray = new byte[total];
in.read(byteArray);
} catch (IOException e) {
e.printStackTrace();
}finally{
if(isClose){
try {
in.close();
} catch (Exception e2) {
System.out.println("关闭流失败");
}
}
}
return byteArray;
}
}
/**
* poi把word中的${image1}替换成图片
* @author
* @date
*/
public class Test {

public static void main(String[] args) throws Exception {

Map<String, Object> param = new HashMap<String, Object>();

Map<String,Object> header = new HashMap<String, Object>();
header.put("width", 512);
header.put("height", 384);
header.put("type", "jpg");
header.put("content", WordUtil.inputStream2ByteArray(new FileInputStream("d:/image1.jpg"), true));
param.put("${image1}",header);

CustomXWPFDocument doc = WordUtil.generateWord(param, "d:\\image.docx");
FileOutputStream fopts = new FileOutputStream("d:/image2.doc");
doc.write(fopts);
fopts.close();
}
}


jacob替换图片

maven依赖

<dependency>
<groupId>net.sf.jacob-project</groupId>
<artifactId>jacob</artifactId>
<version>1.14.3</version>
</dependency>


运行报错时根据提示将dll文件放到java_home/bin下面即可dll文件链接

/**
* 用于给指定的word文档中某处字符串做替换
* @param textPath  待替换的word文档
* @param targetWord   待替换的字符串
* @param replaceWord  要替换成的字符串
*/
public static void replaceWord(String textPath, String targetWord,
String replaceWord) {
ActiveXComponent app = new ActiveXComponent("Word.Application");// 启动word
try {
app.setProperty("Visible", new Variant(false));// 设置word不可见

Dispatch docs = app.getProperty("Documents").toDispatch();

Dispatch doc = Dispatch.invoke(
docs,
"Open",
Dispatch.Method,
new Object[] { textPath, new Variant(false),
new Variant(false) }, new int[1]).toDispatch();
// 打开word文件,注意这里第三个参数要设为false,这个参数表示是否以只读方式打开,
// 因为我们要保存原文件,所以以可写方式打开。

Dispatch selection = app.getProperty("Selection").toDispatch();// 获得对Selection组件

Dispatch.call(selection, "HomeKey", new Variant(6));// 移到开头

Dispatch find = Dispatch.call(selection, "Find").toDispatch();// 获得Find组件

Dispatch.put(find, "Text", targetWord);// 查找字符串targetWord

Dispatch.call(find, "Execute");// 执行查询

Dispatch.put(selection, "Text", replaceWord);// 替换为replaceWord

Dispatch.call(doc, "Save");// 保存

Dispatch.call(doc, "Close", new Variant(false));
} catch (Exception e) {
e.printStackTrace();
} finally {
app.invoke("Quit", new Variant[] {});
app.safeRelease();
}
}

/**
* 创建一个word文档
* @param txtContent 要写入word文档的内容
* @param fileName 要保存的word文档路径
*/
public static void createWordFile(String txtContent, String fileName) {
ActiveXComponent app = new ActiveXComponent("Word.Application");// 启动word

try {
app.setProperty("Visible", new Variant(false));// 设置word不可见
Dispatch docs = app.getProperty("Documents").toDispatch();
Dispatch doc = Dispatch.call(docs, "Add").toDispatch();
Dispatch selection = Dispatch.get(app, "Selection").toDispatch();
Dispatch.put(selection, "Text", txtContent);
Dispatch.call(Dispatch.call(app, "WordBasic").getDispatch(),
"FileSaveAs", fileName);
Variant f = new Variant(false);
Dispatch.call(doc, "Close", f);
} catch (Exception e) {
e.printStackTrace();
} finally {
app.invoke("Quit", new Variant[] {});
app.safeRelease();
}
}

/**
* 根据现有的txt文本来创建word
* @param txt txt文本路径
* @param wordFile word路径
*/
public static void createWordWithTxt(String txt, String wordFile) {
String txtContent = null;
try {
txtContent = bufferedReader(txt);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
createWordFile(txtContent, wordFile);
}

/**
* 读文件
* @param path
* @return
* @throws IOException
*/
public static String bufferedReader(String path) throws IOException {
File file = new File(path);
if (!file.exists() || file.isDirectory())
throw new FileNotFoundException();
BufferedReader br = new BufferedReader(new FileReader(file));
String temp = null;
StringBuffer sb = new StringBuffer();
temp = br.readLine();
while (temp != null) {
sb.append(temp + " ");
temp = br.readLine();
}
return sb.toString();
}

/**
* 给指定的word文档在字符串指定位置插入图片
* @param wordFile word文档
* @param imagePath  待添加图片的路径
* @param tarStr 指定的字符串位置
*/
public static void insertImage(String wordFile, String imagePath,
String tarStr) {
ActiveXComponent app = new ActiveX
b9ca
Component("Word.Application");// 启动word
try {
app.setProperty("Visible", new Variant(false));// 设置word不可见

Dispatch docs = app.getProperty("Documents").toDispatch();

Dispatch doc = Dispatch.invoke(
docs,
"Open",
Dispatch.Method,
new Object[] { wordFile, new Variant(false),
new Variant(false) }, new int[1]).toDispatch();
// 打开word文件,注意这里第三个参数要设为false,这个参数表示是否以只读方式打开,
// 因为我们要保存原文件,所以以可写方式打开。

Dispatch selection = app.getProperty("Selection").toDispatch();

Dispatch.call(selection, "HomeKey", new Variant(6));// 移到开头

Dispatch find = Dispatch.call(selection, "Find").toDispatch();// 获得Find组件

Dispatch.put(find, "Text", tarStr);// 查找字符串tarStr

Dispatch.call(find, "Execute");// 执行查询

Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
"AddPicture", imagePath);// 在指定位置插入图片

Dispatch.call(doc, "Save");// 保存

Dispatch.call(doc, "Close", new Variant(false));
} catch (Exception e) {
e.printStackTrace();
} finally {
app.invoke("Quit", new Variant[] {});
app.safeRelease();
}
}
/**
* 给指定的word文档在字符串指定位置插入图片
* @param wordFile word文档
* @param replaceInfos  待添加图片的信息
*/
public static void replaceImage(String wordFile,List<Map<String,String>> replaceInfos) {
ActiveXComponent app = new ActiveXComponent("Word.Application");// 启动word
try {
app.setProperty("Visible", new Variant(false));// 设置word不可见

Dispatch docs = app.getProperty("Documents").toDispatch();

Dispatch doc = Dispatch.invoke(
docs,
"Open",
Dispatch.Method,
new Object[] { wordFile, new Variant(false),
new Variant(false) }, new int[1]).toDispatch();
// 打开word文件,注意这里第三个参数要设为false,这个参数表示是否以只读方式打开,
// 因为我们要保存原文件,所以以可写方式打开。

Dispatch selection = app.getProperty("Selection").toDispatch();

Dispatch.call(selection, "HomeKey", new Variant(6));// 移到开头

Dispatch find = Dispatch.call(selection, "Find").toDispatch();// 获得Find组件

for(int i=0;i<replaceInfos.size();i++){
Map<String,String> info=replaceInfos.get(i);
Dispatch.put(find, "Text", info.get("tarStr"));// 查找字符串tarStr

Dispatch.call(find, "Execute");// 执行查询

Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
"AddPicture", info.get("imagePath"));// 在指定位置插入图片

Dispatch.put(find, "Text", info.get("tarStr"));// 查找字符串targetWord

Dispatch.call(find, "Execute");// 执行查询

Dispatch.put(selection, "Text", "");// 替换为replaceWord
}

Dispatch.call(doc, "Save");// 保存

Dispatch.call(doc, "Close", new Variant(false));
} catch (Exception e) {
e.printStackTrace();
} finally {
app.invoke("Quit", new Variant[] {});
app.safeRelease();
}
}

/**
* 在指定word文档的指定位置创建一个表格
* @param wordFile 指定word文档
* @param pos 指定位置
* @param numCols 列数
* @param numRows 行数
*/
public static void createTable(String wordFile, String pos, int numCols,
int numRows) {
ActiveXComponent app = new ActiveXComponent("Word.Application");// 启动word
Dispatch selection = null;
Dispatch doc = null;
Dispatch docs = null;
boolean b = false;
try {
app.setProperty("Visible", new Variant(false));// 设置word不可见

docs = app.getProperty("Documents").toDispatch();

doc = Dispatch.invoke(
docs,
"Open",
Dispatch.Method,
new Object[] { wordFile, new Variant(false),
new Variant(false) }, new int[1]).toDispatch();
// 打开word文件,注意这里第三个参数要设为false,这个参数表示是否以只读方式打开,
// 因为我们要保存原文件,所以以可写方式打开。

selection = app.getProperty("Selection").toDispatch();
} catch (Exception e) {
e.printStackTrace();
}
if (pos == null || pos.equals(""))
b = false;
// 从selection所在位置开始查询
Dispatch find = app.call(selection, "Find").toDispatch();
// 设置要查找的内容
Dispatch.put(find, "Text", pos);
// 向前查找
Dispatch.put(find, "Forward", "True");
// 设置格式
Dispatch.put(find, "Format", "True");
// 大小写匹配
Dispatch.put(find, "MatchCase", "True");
// 全字匹配
Dispatch.put(find, "MatchWholeWord", "True");
// 查找并选中
b = Dispatch.call(find, "Execute").getBoolean();
// 创建表格
if (b) {
Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
Dispatch range = Dispatch.get(selection, "Range").toDispatch();
Dispatch newTable = Dispatch.call(tables, "Add", range,
new Variant(numRows), new Variant(numCols)).toDispatch();
Dispatch.call(selection, "MoveRight");
} else
System.out.println("没有找到指定的位置,请检查是否存在这样的位置。");
try {
Dispatch.call(doc, "Save");// 保存
Dispatch.call(doc, "Close", new Variant(false));
} catch (Exception e) {
e.printStackTrace();
} finally {
app.invoke("Quit", new Variant[] {});
app.safeRelease();
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
WordUtil2.insertImage("d:/简报.docx", "d:/image1.jpg", "37fb7787d0354d42be01328b2e19d065");
/* System.out.println("Hello! World");
System.out.println(System.getProperty("java.library.path"));*/
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息