package org.foreverframework.office;
import java.io.File;
public class MSWordUtil {
private static final String COLUMNS = "Columns";
private static final String CELLS = "Cells";
private static final String ROWS = "Rows";
private static final String COUNT = "Count";
private static final String TABLES = "Tables";
private static final String ITEM = "Item";
private static final String CELL = "Cell";
private static final String RANGE = "Range";
private static final String TOP = "Top";
private static final String LEFT = "Left";
private static final String Z_ORDER = "ZOrder";
private static final String CONVERT_TO_SHAPE = "ConvertToShape";
private static final String HEIGHT = "Height";
private static final String WIDTH = "Width";
private static final String ADD_PICTURE = "AddPicture";
private static final String INLINE_SHAPES = "InlineShapes";
private static final String MATCH_ALL_WORD_FORMS = "MatchAllWordForms";
private static final String MATCH_SOUNDS_LIKE = "MatchSoundsLike";
private static final String MATCH_WILDCARDS = "MatchWildcards";
private static final String MATCH_BYTE = "MatchByte";
private static final String MATCH_WHOLE_WORD = "MatchWholeWord";
private static final String MATCH_CASE = "MatchCase";
private static final String FORMAT = "Format";
private static final String FORWARD = "Forward";
private static final String EXECUTE = "Execute";
private static final String FALSE = "False";
private static final String TRUE = "True";
private static final String CLEAR_FORMATTING = "ClearFormatting";
private static final String SAVE_AS = "saveAs";
private static final String FIND = "Find";
private static final String HOME_KEY = "HomeKey";
private static final String TEXT = "Text";
private static final String SELECTION = "Selection";
private static final String DOCUMENTS = "Documents";
private static final String VISIBLE = "Visible";
private static final String OPEN = "Open";
private static final String QUIT = "Quit";
private static final String CLOSE = "Close";
private static final int wdFormatPDF = 17;
private static final int wdDoNotSaveChanges = 0;
protected static final Integer UNIT_WDSTORY = new Integer(6);// 移动光标至文档开始
protected static final Integer UNIT_WDLINE = new Integer(5);// 选择当前行
private static Logger log = LoggerFactory.getLogger(MSWordUtil.class);
public static final String WORD_APP = "Word.Application";
protected IDispatch doc;
protected Map<String, IDispatch> docs;
protected IDispatch documents;
protected String newFileName;
protected static ReleaseManager rm;
protected IDispatch word;
static {
log.info("加载jcom.dll");
URL url = MSWordUtil.class.getClassLoader().getResource("jcom.dll");
String filePath = url.getFile();
log.info("jcom.dll文件存放路径:" + filePath);
System.load(filePath);
rm = new ReleaseManager();
}
public MSWordUtil() {
try {
word = new IDispatch(rm, WORD_APP);
word.put(VISIBLE, new Boolean(true));
documents = (IDispatch) word.get(DOCUMENTS);
docs = new HashMap<String, IDispatch>();
} catch (JComException e) {
throw new RuntimeException("初始化word程序出错。服务器没有安装word程序");
}
}
public IDispatch open(String fileName) throws Exception {
File file = new File(fileName);
if (file.exists()) {
doc = (IDispatch) documents.method(OPEN, new Object[] { fileName });
docs.put(fileName, doc);
} else {
throw new Exception("文件不存在:" + fileName);
}
return doc;
}
public void closeDoc(IDispatch doc, boolean saveOnExit) throws Exception {
doc.method(CLOSE, new Object[] { new Boolean(saveOnExit) });
}
public void closeAllDoc(boolean saveOnExit) throws Exception {
for (IDispatch doc : docs.values()) {
doc.method(CLOSE, new Object[] { new Boolean(saveOnExit) });
}
}
public void quit(int wdDoNotSaveChanges) throws Exception {
word.method(QUIT, new Object[] { wdDoNotSaveChanges });
}
public void quit() throws Exception {
word.method(QUIT, new Object[] { wdDoNotSaveChanges });
}
protected IDispatch getSelection() throws Exception {
return (IDispatch) word.get(SELECTION);
}
protected boolean find(String findText) throws Exception {
IDispatch find = (IDispatch) getSelection().get(FIND);
find.method(CLEAR_FORMATTING, null);
find.put(TEXT, findText);
find.put(FORWARD, TRUE);
find.put(FORMAT, FALSE);
find.put(MATCH_CASE, TRUE);
find.put(MATCH_WHOLE_WORD, FALSE);
find.put(MATCH_BYTE, TRUE);
find.put(MATCH_WILDCARDS, FALSE);
find.put(MATCH_SOUNDS_LIKE, FALSE);
find.put(MATCH_ALL_WORD_FORMS, FALSE);
return new Boolean(find.method(EXECUTE, null).toString());
}
public boolean replace(String findText, String newText) throws Exception {
boolean leaf = false;
if (find(findText)) {
getSelection().put(TEXT, newText);
getSelection().method(HOME_KEY, new Object[] { UNIT_WDSTORY });
leaf = true;
}
return leaf;
}
public boolean replaceAll(String findText, String replaceText)
throws Exception {
boolean leaf = false;
while (find(findText)) {
getSelection().put(TEXT, replaceText);
getSelection().method(HOME_KEY, new Object[] { UNIT_WDSTORY });
leaf = true;
}
return leaf;
}
protected void replaceImage(IDispatch selection, String imagePath)
throws Exception {
IDispatch inlineShapes = (IDispatch) selection.get(INLINE_SHAPES);
inlineShapes.method(ADD_PICTURE, new Object[] { imagePath });
}
protected void replaceImage(IDispatch selection, String imagePath,
int ZOrder, int width, int height) throws Exception {
IDispatch inlineShapes = (IDispatch) selection.get(INLINE_SHAPES);
IDispatch image = (IDispatch) inlineShapes.method(ADD_PICTURE,
new Object[] { imagePath });
if (width == 0 && height == 0) {
ImageIcon imageIcon = new ImageIcon(imagePath);
width = imageIcon.getIconWidth();
height = imageIcon.getIconHeight();
}
image.put(WIDTH, width);
image.put(HEIGHT, height);
IDispatch shape = null;
try {
Thread.sleep(500);
shape = (IDispatch) image.method(CONVERT_TO_SHAPE, null);
} catch (Exception e) {
throw new Exception("插入图片出错");
}
shape.method(Z_ORDER, new Object[] { ZOrder });
Float left = Float.parseFloat(shape.get(LEFT).toString());
Float top = Float.parseFloat(shape.get(TOP).toString());
shape.method("IncrementTop", new Object[] { -height / 2 });
log.info("left=" + left + ":top=" + top);
}
public boolean replaceImage(String toFindText, String imagePath)
throws Exception {
boolean leaf = false;
if (find(toFindText)) {
replaceImage(getSelection(), imagePath);
getSelection().method(HOME_KEY, new Object[] { UNIT_WDSTORY });
leaf = true;
}
return leaf;
}
/**
* 查找toFindText,替换成指定的图片
*
* @param toFindText
* - String 欲替换的文本
* @param imagePath
* - String 图片文件全路径
* @param ZOrder
* - String 图片版式 4浮于文字上方,5浮于文字下方
* @return
* @throws Exception
*/
public boolean replaceImage(String toFindText, String imagePath,
int ZOrder, int width, int height) throws Exception {
boolean leaf = false;
if (find(toFindText)) {
replaceImage(getSelection(), imagePath, ZOrder, width, height);
getSelection().method(HOME_KEY, new Object[] { UNIT_WDSTORY });
leaf = true;
}
return leaf;
}
/**
* 查找toFindText,替换成指定的图片
*
* @param toFindText
* - String 欲替换的文本
* @param imagePath
* - String 图片文件全路径
* @param ZOrder
* - String 图片版式 4浮于文字上方,5浮于文字下方
* @return
* @throws Exception
*/
public boolean replaceAllImage(String toFindText, String imagePath,
int ZOrder, int width, int height) throws Exception {
boolean leaf = false;
while (find(toFindText)) {
replaceImage(getSelection(), imagePath, ZOrder, width, height);
getSelection().method("HomeKey", new Object[] { new Integer(6) });
leaf = true;
}
return leaf;
}
/**
* 查找toFindText,并替换为指定的word文件内容
*
* @param toFindText
* - String 欲替换的文本
* @param docFile
* - String doc文件的全路径
* @throws Exception
*/
public boolean replaceFile(String toFindText, String docFile)
throws Exception {
boolean leaf = false;
if (find(toFindText)) {
replaceFile(getSelection(), docFile);
getSelection().method("HomeKey", new Object[] { new Integer(6) });
leaf = true;
}
return leaf;
}
protected void replaceFile(IDispatch selection, String docFile)
throws Exception {
selection.method("insertFile", new Object[] { docFile, "",
new Boolean(false), new Boolean(false), new Boolean(false) });
selection.method("TypeBackspace", null);
}
/**
* 查找toFindText,并替换为指定的word文件内容
*
* @param toFindText
* - String 欲替换的文本
* @param docFile
* - String doc文件的全路径
* @throws Exception
*/
public boolean replaceAllFile(String toFindText, String docFile)
throws Exception {
boolean leaf = false;
while (find(toFindText)) {
replaceFile(getSelection(), docFile);
getSelection().method("HomeKey", new Object[] { new Integer(6) });
leaf = true;
}
return leaf;
}
protected void insertTable(IDispatch range, List<Object[]> dataList)
throws Exception {
IDispatch table;
if (dataList.size() < 1) {
System.out.println("Empty table!");
return;
}
Object titleData[] = dataList.get(0);
int rowLength = dataList.size();
int colLength = titleData.length;
IDispatch tables = (IDispatch) doc.get(TABLES);
table = (IDispatch) tables.method("Add", new Object[] { range,
rowLength, colLength });
for (int i = 1; i <= rowLength; i++) {
Object datas[] = dataList.get(i - 1);
for (int j = 1; j <= datas.length; j++) {
IDispatch cell = (IDispatch) table.method(CELL, new Object[] {
new Integer(i), new Integer(j) });
IDispatch cellRange = (IDispatch) cell.get(RANGE);
cellRange.put("Text", datas[j - 1]);
}
}
}
/**
* 在指定行后面添加count行
*
* @param tbIndex
* 指定表格
* @param rowIndex
* 第几行
* @param count
* 添加几行
* @return
* @throws Exception
*/
public boolean insertTabRow(int tbIndex, int rowIndex, int colIndex,
int count) throws Exception {
IDispatch cell = getTabCell(tbIndex, rowIndex, colIndex);
IDispatch range = (IDispatch) cell.get(RANGE);
range.method("select", null);
getSelection().method("InsertRowsBelow", new Object[] { count });
return true;
}
public boolean insertTabRow(int tbIndex) throws Exception {
IDispatch rows = getRows(tbIndex);
rows.method("Add", null);
return true;
}
/**
* 填充表格数据 如果输入的数据宽度(列数)超出模板设置,则超出的部分不会被插入
*
* @throws Exception
*/
public void replaceTable(int tbIndex, int fromRow, int fromCol,
List<Object[]> dataList) throws Exception {
if (dataList.size() < 1) {
System.out.println("Empty table!");
return;
}
IDispatch rows = getRows(tbIndex);
int rowsCount = getTabRowCount(tbIndex);
int columnsCount = getTabColCount(tbIndex);
if (fromRow > rowsCount) {
for (int i = 0; i < fromRow - rowsCount; i++) {
rows.method("Add", null);
}
} else if (fromRow == -1) {
fromRow = rowsCount;
}
int rowSum = 0;
for (int i = fromRow, index = 0; index < dataList.size(); i++, index++) {
Object datas[] = dataList.get(index);
List<List<?>> rowChildList = new ArrayList<List<?>>();
List<Integer[]> list = new ArrayList<Integer[]>();
for (int j = fromCol, h = 0; h < datas.length && j <= columnsCount; j++, h++) {
Object item = datas[h];
int rowChildColSum = 0;
for (Object object : rowChildList) {
Object[] array = ((Object[]) ((List<?>) object).get(0));
if (array.length > 1) {
rowChildColSum += array.length - 1;
} else {
rowChildColSum += 1;
}
}
if (item instanceof java.lang.String) {
setCellText(tbIndex, i + rowSum, (rowChildColSum > 0 ? j
+ rowChildColSum : j), datas[h] == null ? ""
: datas[h].toString());
} else if (item instanceof java.util.List<?>) {
List<?> childDataList = (List<?>) item;
if (childDataList.size() == 0)
continue;
int numRows = childDataList.size();
int numColumns = 0;
int lastRowMergeNum = 0;
for (Object object : childDataList) {
Object[] dataA = (Object[]) object;
if (dataA.length > numColumns) {
numColumns = dataA.length;
}
lastRowMergeNum = dataA.length;
}
splitCell(tbIndex, i + rowSum, (rowChildColSum > 0 ? j
+ rowChildColSum : j), numRows, numColumns);
list.add(new Integer[] { j, lastRowMergeNum });
for (int k = 0; k < childDataList.size(); k++) {
Object[] dataA = (Object[]) childDataList.get(k);
if (dataA.length < numColumns) {
rowChildColSum = 0;
for (Object object : rowChildList) {
rowChildColSum += ((Object[]) ((List<?>) object)
.get(k)).length - 1;
}
int form_Col = rowChildColSum > 0 ? j
+ rowChildColSum : j;
mergeCell(tbIndex, i + rowSum + k, form_Col, i
+ rowSum + k, form_Col + numColumns
- dataA.length);
}
}
for (int k = 0; k < childDataList.size(); k++) {
Object[] dataA = (Object[]) childDataList.get(k);
rowChildColSum = 0;
for (Object object : rowChildList) {
rowChildColSum += ((Object[]) ((List<?>) object)
.get(k)).length - 1;
}
for (int l = 0; l < dataA.length; l++) {
setCellText(tbIndex, i + rowSum + k, l
+ (rowChildColSum > 0 ? j + rowChildColSum
: j), dataA[l].toString());
}
}
rowChildList.add(childDataList);
} else {
throw new Exception("传入的集合格式不正确!");
}
}
int maxRowSum = 0;
for (Object item : datas) {
if (item instanceof java.util.List<?>) {
if (maxRowSum < ((List<?>) item).size()) {
maxRowSum = ((List<?>) item).size();
}
}
}
rowSum += (maxRowSum > 1 ? maxRowSum - 1 : 0);
if (index + 1 != dataList.size()) {
rows.method("Add", null);
for (Integer[] array : list) {
mergeCell(tbIndex, i + rowSum + 1, array[0],
i + rowSum + 1, array[0] + array[1] - 1);
}
}
}
}
/**
* 拆分指定单元格为指定的几行几列
*
* @param tbIndex
* @param fromRow
* @param fromCol
* @param numRows
* @param numColumns
* @throws Exception
*/
public void splitCell(int tbIndex, int fromRow, int fromCol, int numRows,
int numColumns) throws Exception {
IDispatch cell = getTabCell(tbIndex, fromRow, fromCol);
cell.method("split", new Object[] { numRows, numColumns });
}
/**
* 合并单元格
*
* @param tbIndex
* @param fromRow
* @param fromCol
* @param toRow
* @param toCol
* @throws Exception
*/
public void mergeCell(int tbIndex, int fromRow, int fromCol, int toRow,
int toCol) throws Exception {
int rowsCount = getTabRowCount(tbIndex);
if (fromRow < 1 || fromRow > rowsCount)
fromRow = 1;
if (toRow < 1 || toRow > rowsCount)
toRow = rowsCount;
int Columnscount = getTabColCount(tbIndex);
if (fromCol < 1 || fromCol > Columnscount)
fromCol = 1;
if (toCol < 1 || toCol > Columnscount)
toCol = Columnscount;
IDispatch fromCell = getTabCell(tbIndex, fromRow, fromCol);
IDispatch toCell = getTabCell(tbIndex, toRow, toCol);
fromCell.method("Merge", new Object[] { toCell });
}
/**
* 填充指定单元格文本内容
*
* @param tbIndex
* @param row
* @param col
* @param text
* @throws Exception
*/
public void setCellText(int tbIndex, int row, int col, String text)
throws Exception {
IDispatch cell = null;
try {
cell = getTabCell(tbIndex, row, col);
} catch (Exception e) {
throw new Exception("获取单元格:" + row + "行" + col + "列失败");
}
IDispatch cellRange = (IDispatch) cell.get(RANGE);
cellRange.put("Text", text);
}
protected IDispatch getRows(int tbIndex) throws Exception {
IDispatch table = getTable(tbIndex);
return (IDispatch) table.get(ROWS);
}
protected IDispatch getCloumn(int tbIndex) throws Exception {
IDispatch table = getTable(tbIndex);
return (IDispatch) table.get(COLUMNS);
}
/**
* 获取指定表格有多少列
*
* @param tbIndex
* - int 表格索引
* @return 返回该表格由多少列组成
* @throws Exception
*/
public int getTabColCount(int tbIndex) throws Exception {
IDispatch Columns = (IDispatch) getTable(tbIndex).get(COLUMNS);
return (Integer) Columns.get(COUNT);
}
/**
* 获取指定表格的指定行的列数
*
* @param tbIndex
* @param rowIndex
* @return
* @throws Exception
*/
public int getTabRowColCount(int tbIndex, int rowIndex) throws Exception {
IDispatch row = getTabRow(tbIndex, rowIndex);
// row.method("Select", null);
IDispatch cells = (IDispatch) row.get(CELLS);
return (Integer) cells.get(COUNT);
}
/**
* 获取指定表格有多少行
*
* @param tbIndex
* - int 表格索引
* @return 返回该表格由多少行组成
* @throws Exception
*/
public int getTabRowCount(int tbIndex) throws Exception {
IDispatch rows = (IDispatch) getTable(tbIndex).get(ROWS);
return (Integer) rows.get(COUNT);
}
/**
* 获取指定索引的表格对象
*
* @param tbIndex
* @return
* @throws Exception
*/
protected IDispatch getTable(int tbIndex) throws Exception {
IDispatch tables = (IDispatch) doc.get(TABLES);
try {
return (IDispatch) tables.method(ITEM, new Object[] { tbIndex });
} catch (Exception e) {
throw new Exception("索引为:" + tbIndex + "的表格不存在!");
}
}
protected IDispatch getTabRow(int tbIndex, int rowIndex) throws Exception {
IDispatch rows = getRows(tbIndex);
IDispatch row = (IDispatch) rows
.method(ITEM, new Object[] { rowIndex });
return row;
}
/**
* 删除指定表格的指定行
*
* @param tbIndex
* - int 表格索引
* @param rowIndex
* - int 表格行索引
* @throws Exception
*/
public void delTabRow(int tbIndex, int rowIndex) throws Exception {
IDispatch row = getTabRow(tbIndex, rowIndex);
row.method("Select", null);
row.method("Delete", null);
}
protected IDispatch getTabCell(int tbIndex, int row, int col)
throws Exception {
return (IDispatch) getTable(tbIndex).method(CELL,
new Object[] { new Integer(row), new Integer(col) });
}
/**
* 判断指定行是否是空行,就是该行的每个单元格内容为空
*
* @param tbIndex
* @param rowIndex
* @return
* @throws Exception
*/
public boolean rowIsEmpty(int tbIndex, int rowIndex) throws Exception {
int cols = getTabColCount(tbIndex);
for (int i = 1; i <= cols; i++) {
IDispatch cell = getTabCell(tbIndex, rowIndex, i);
IDispatch cellRange = (IDispatch) cell.get(RANGE);
String cellText = cellRange.get(TEXT).toString();
if (!"\r".equals(cellText)) {
return false;
}
}
return true;
}
/**
* 获取word中指定表格的数据,以java集合形式返回
*
* @param i
* @return
* @throws Exception
*/
public List<String[]> tableToList(int tbIndex) throws Exception {
List<String[]> dataList = new ArrayList<String[]>();
int rows = getTabRowCount(tbIndex);
int cols = getTabColCount(tbIndex);
for (int i = 1; i <= rows; i++) {
String[] rowItem = new String[cols];
for (int j = 1; j <= cols; j++) {
IDispatch cell = getTabCell(tbIndex, i, j);
IDispatch range = (IDispatch) cell.get(RANGE);
rowItem[j - 1] = range.get(TEXT).toString();
}
dataList.add(rowItem);
}
return dataList;
}
public boolean savePDF(String inputFile, String outputFile)
throws Exception {
IDispatch doc = open(inputFile);
doc.method(SAVE_AS, new Object[] { outputFile, wdFormatPDF });
return true;
}
public boolean savePDF(String outputFile) throws Exception {
doc.method(SAVE_AS, new Object[] { outputFile, wdFormatPDF });
return true;
}
public void saveDoc(String outputFile) throws Exception {
doc.method(SAVE_AS, new Object[] { outputFile, new Integer(0) });
}
protected void moveDown(IDispatch selection, int count) throws Exception {
for (int i = 0; i < count; i++) {
selection.method("MoveDown", null);
}
}
protected void moveDown(int count) throws Exception {
moveDown(getSelection(), count);
}
protected void moveLeft(IDispatch selection, int count) throws Exception {
for (int i = 0; i < count; i++) {
selection.method("MoveLeft", null);
}
}
protected void moveLeft(int count) throws Exception {
moveLeft(getSelection(), count);
}
protected void moveRight(IDispatch selection, int count) throws Exception {
for (int i = 0; i < count; i++) {
selection.method("MoveRight", null);
}
}
protected void moveStart(IDispatch selection) throws Exception {
selection.method("HomeKey", new Object[] { 6 });
}
protected void moveUp(IDispatch selection, int count) throws Exception {
for (int i = 0; i < count; i++) {
selection.method("MoveUp", null);
}
}
protected void moveUp(int count) throws Exception {
moveUp(getSelection(), count);
}
}