Jacob的下载、配置就不说了,提醒下,官方的提供的17版本似乎不支持jdk1.5,得下载19版的(CSDN上有)。
研究这个的目的是想用java生成符合格式的word文档,文档内容大体上有三种格式,Heading1、Heading2和Normal,在word的文档结构图显示的样子如下
Heading 1
Heading 2
Heading 2
Heading 2
Heading 1
Heading 2
Heading 2
最初想直接生成,但发现设置格式实在是件头痛的事,本人对word编程不了解,试了几次均未实现Heading格式,不知道怎样设置才能在word的文档结构图中体现。改变思路,先定义个模板,然后直接替换模板中的内容,由于内容是不固定的(Heading 1个数不固定,每个Heading 1下的Heading 2个数不固定),因此不能直接替换,得根据需要拷贝模板文档中的格式到新文档,然后再替换为自己的内容。
就在这个拷贝上折腾了我半天,用find选中拷贝,发现格式丢失了;把格式内容放在表格里再取表格内容拷贝,发现连同cell的那个框框一起拷贝过去了,不知道是不是我写错了,谁知道指点下,代码如下:
Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex)).toDispatch();
Dispatch cell = Dispatch.call(table, "Cell", new Variant(cellRowIdx),new Variant(cellColIdx)).toDispatch();
//Dispatch.call(cell, "Select");
Dispatch range = Dispatch.get(cell, "Range").toDispatch();
Dispatch.call(range, "Copy");
最后采用了拷贝段落的方式解决了问题。
最终思路:定义模板,每种样式一种标记占一个段落-根据实际需要拷贝段落内容到新文档-替换段落内容。这样就可以生成任何格式的word文档了。
template.doc内容:
$Title$
$Heading 1$
$Heading 2$
$Normal$
word控制参考代码:
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;


public class MSWordManager
{
// word文档
private Dispatch doc;

// word运行程序对象
private ActiveXComponent word;

// 所有word文档集合
private Dispatch documents;

// 选定的范围或插入点
private Dispatch selection;

private boolean saveOnExit = true;


/** *//**
*
* @param visible 为true表示word应用程序可见
*/

public MSWordManager(boolean visible)
{

if (word == null)
{
word = new ActiveXComponent("Word.Application");
word.setProperty("Visible", new Variant(visible));
}
if (documents == null)
documents = word.getProperty("Documents").toDispatch();
}


/** *//**
* 设置退出时参数
*
* @param saveOnExit boolean true-退出时保存文件,false-退出时不保存文件
*/

public void setSaveOnExit(boolean saveOnExit)
{
this.saveOnExit = saveOnExit;
}


/** *//**
* 创建一个新的word文档
*
*/

public void createNewDocument()
{
doc = Dispatch.call(documents, "Add").toDispatch();
selection = Dispatch.get(word, "Selection").toDispatch();
}


/** *//**
* 打开一个已存在的文档
*
* @param docPath
*/

public void openDocument(String docPath)
{
closeDocument();
doc = Dispatch.call(documents, "Open", docPath).toDispatch();
selection = Dispatch.get(word, "Selection").toDispatch();
}


/** *//**
* 把选定的内容或插入点向上移动
*
* @param pos 移动的距离
*/

public void moveUp(int pos)
{
if (selection == null)
selection = Dispatch.get(word, "Selection").toDispatch();
for (int i = 0; i < pos; i++)
Dispatch.call(selection, "MoveUp");

}


/** *//**
* 把选定的内容或者插入点向下移动
*
* @param pos 移动的距离
*/

public void moveDown(int pos)
{
if (selection == null)
selection = Dispatch.get(word, "Selection").toDispatch();
for (int i = 0; i < pos; i++)
Dispatch.call(selection, "MoveDown");
}


/** *//**
* 把选定的内容或者插入点向左移动
*
* @param pos 移动的距离
*/

public void moveLeft(int pos)
{
if (selection == null)
selection = Dispatch.get(word, "Selection").toDispatch();

for (int i = 0; i < pos; i++)
{
Dispatch.call(selection, "MoveLeft");
}
}


/** *//**
* 把选定的内容或者插入点向右移动
*
* @param pos 移动的距离
*/

public void moveRight(int pos)
{
if (selection == null)
selection = Dispatch.get(word, "Selection").toDispatch();
for (int i = 0; i < pos; i++)
Dispatch.call(selection, "MoveRight");
}


/** *//**
* 把插入点移动到文件首位置
*
*/

public void moveStart()
{
if (selection == null)
selection = Dispatch.get(word, "Selection").toDispatch();
Dispatch.call(selection, "HomeKey", new Variant(6));
}


/** *//**
* 从选定内容或插入点开始查找文本
*
* @param toFindText 要查找的文本
* @return boolean true-查找到并选中该文本,false-未查找到文本
*/

public boolean find(String toFindText)
{
if (toFindText == null || toFindText.equals(""))
return false;
// 从selection所在位置开始查询
Dispatch find = word.call(selection, "Find").toDispatch();
// 设置要查找的内容
Dispatch.put(find, "Text", toFindText);
// 向前查找
Dispatch.put(find, "Forward", "True");
// 设置格式
Dispatch.put(find, "Format", "True");
// 大小写匹配
Dispatch.put(find, "MatchCase", "True");
// 全字匹配
Dispatch.put(find, "MatchWholeWord", "True");
// 查找并选中
return Dispatch.call(find, "Execute").getBoolean();
}


/** *//**
* 把选定选定内容设定为替换文本
*
* @param toFindText 查找字符串
* @param newText 要替换的内容
* @return
*/

public boolean replaceText(String toFindText, String newText)
{
if (!find(toFindText))
return false;
Dispatch.put(selection, "Text", newText);
return true;
}


/** *//**
* 全局替换文本
*
* @param toFindText 查找字符串
* @param newText 要替换的内容
*/

public void replaceAllText(String toFindText, String newText)
{

while (find(toFindText))
{
Dispatch.put(selection, "Text", newText);
Dispatch.call(selection, "MoveRight");
}
}


/** *//**
* 在当前插入点插入字符串
*
* @param newText 要插入的新字符串
*/

public void insertText(String newText)
{
Dispatch.put(selection, "Text", newText);
}


/** *//**
*
* @param toFindText 要查找的字符串
* @param imagePath 图片路径
* @return
*/

public boolean replaceImage(String toFindText, String imagePath)
{
if (!find(toFindText))
return false;
Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
"AddPicture", imagePath);
return true;
}


/** *//**
* 全局替换图片
*
* @param toFindText 查找字符串
* @param imagePath 图片路径
*/

public void replaceAllImage(String toFindText, String imagePath)
{

while (find(toFindText))
{
Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
"AddPicture", imagePath);
Dispatch.call(selection, "MoveRight");
}
}


/** *//**
* 在当前插入点插入图片
*
* @param imagePath 图片路径
*/

public void insertImage(String imagePath)
{
Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
"AddPicture", imagePath);
}


/** *//**
* 合并单元格
*
* @param tableIndex
* @param fstCellRowIdx
* @param fstCellColIdx
* @param secCellRowIdx
* @param secCellColIdx
*/
public void mergeCell(int tableIndex, int fstCellRowIdx, int fstCellColIdx,

int secCellRowIdx, int secCellColIdx)
{
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
.toDispatch();
Dispatch fstCell = Dispatch.call(table, "Cell",
new Variant(fstCellRowIdx), new Variant(fstCellColIdx))
.toDispatch();
Dispatch secCell = Dispatch.call(table, "Cell",
new Variant(secCellRowIdx), new Variant(secCellColIdx))
.toDispatch();
Dispatch.call(fstCell, "Merge", secCell);
}


/** *//**
* 在指定的单元格里填写数据
*
* @param tableIndex
* @param cellRowIdx
* @param cellColIdx
* @param txt
*/
public void putTxtToCell(int tableIndex, int cellRowIdx, int cellColIdx,

String txt)
{
// 所有表格
Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
// 要填充的表格
Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
.toDispatch();
Dispatch cell = Dispatch.call(table, "Cell", new Variant(cellRowIdx),
new Variant(cellColIdx)).toDispatch();
Dispatch.call(cell, "Select");
Dispatch.put(selection, "Text", txt);
}


/** *//**
* 在当前文档拷贝数据
*
* @param pos
*/

public void copy(String toCopyText)
{
moveStart();

if (this.find(toCopyText))
{
Dispatch textRange = Dispatch.get(selection, "Range").toDispatch();
Dispatch.call(textRange, "Copy");
}
}


/** *//**
* 在当前文档粘帖剪贴板数据
*
* @param pos
*/

public void paste(String pos)
{
moveStart();

if (this.find(pos))
{
Dispatch textRange = Dispatch.get(selection, "Range").toDispatch();
Dispatch.call(textRange, "Paste");
}
}


/** *//**
* 在当前文档指定的位置拷贝表格
*
* @param pos 当前文档指定的位置
* @param tableIndex 被拷贝的表格在word文档中所处的位置
*/

public void copyTable(String pos, int tableIndex)
{
Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
.toDispatch();
Dispatch range = Dispatch.get(table, "Range").toDispatch();
Dispatch.call(range, "Copy");

if (this.find(pos))