不知大家在对Word操作时,有没有遇到需要对指定内容进行替换这种需求。前几天公司有个需求,就是对PDF邀请函的姓名那部分内容进行替换,因为本人以前对Word的书签有过操作,所以思路就是通过将这部分内容设定为书签,对书签的进行替换保存为新的邀请函。
用到的lib包括,特别强调下,jacob使用时需要给C:/WINDOWS/System32目录下添加jacob对应位数的dll文件:
具体的步骤如下:
1、首先将PDF转化为WORD文档,替换书签个人感觉WORD操作起来比较方便点,替换后的格式或许有稍许错位,重新编译保存下,将该WORD文档作为邀请函模板;
2、对需要替换的部分添加书签,对邀请人的xx添加书签,暂且命名为xm;
3、替换的内容是以EXCEL存储的单列数据,又引入POI操作EXCEL部分的内容,该类就是POI读取EXCEL内容的公共类,包括XLS以及XLSX;
public class parseExcelFile {
public static final String OFFICE_EXCEL_2003_POSTFIX = "xls";
public static final String OFFICE_EXCEL_2010_POSTFIX = "xlsx";
public static final String EMPTY = "";
public static final String POINT = ".";
public static final String NOT_EXCEL_FILE = " : Not the Excel file!";
public static final String PROCESSING = "Processing...";
/**
* 读Excel文件
*
* @param file
* Ecxel文件
* @param sheetNum
* 第几个sheet 必须大于0或为null(默认1) 否则会报错
* @param startLine
* 开始行(包含本行) 必须大于0或为null(默认1) 否则会报错
* @param endLine
* 结束行(包含本行) 必须大于等于开始行或为null(默认最大行) 否则会报错
* @param startColumn
* 开始列(包含本列) 必须大于0或为null(默认1) 否则会报错
* @param endColumn
* 结束列(包含本列) 必须大于等于开始列或为null(默认第一行列数) 否则会报错
* @return
* @throws IOException
*/
public Map readExcel(File file, Integer sheetNum, Integer startLine, Integer endLine,
Integer startColumn, Integer endColumn) throws IOException {
if (file == null || EMPTY.equals(file)) {
return null;
} else {
String postfix = this.getPostfix(file.getName());
if (!EMPTY.equals(postfix)) {
if (OFFICE_EXCEL_2003_POSTFIX.equals(postfix)) {
return readXls(file, sheetNum, startLine, endLine, startColumn, endColumn);
} else if (OFFICE_EXCEL_2010_POSTFIX.equals(postfix)) {
return readXlsx(file, sheetNum, startLine, endLine, startColumn, endColumn);
}
} else {
System.out.println(file + NOT_EXCEL_FILE);
}
}
return null;
}
/**
* 读2010 xlsx Excel文件
*
* @param 文件路径
* @param sheetNum
* 第几个sheet
* @param startLine
* 开始行
* @param endLine
* 结束行
* @param startColumn
* 开始列
* @param endColumn
* 结束列
* @return
* @throws IOException
*/
public Map readXlsx(File file, Integer sheetNum, Integer startLine, Integer endLine,
Integer startColumn, Integer endColumn) throws IOException {
System.out.println(PROCESSING + file.getName());
InputStream is = new FileInputStream(file);
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
Map map = new HashMap();
// Read the Sheet
// for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets();
// numSheet++) {
if (sheetNum == null || sheetNum.equals("")) {
sheetNum = 1;
map.put("sheetNum", sheetNum.toString());
}
XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(sheetNum - 1);
if (xssfSheet != null) {
if (startLine == null || EMPTY.equals(startLine)) {
startLine = 1;
map.put("startLine", startLine.toString());
}
if (endLine == null || EMPTY.equals(endLine)) {
endLine = xssfSheet.getLastRowNum() + 1;
map.put("endLine", endLine.toString());
}
if (startColumn == null || EMPTY.equals(startColumn)) {
startColumn = 1;
map.put("startColumn", startColumn.toString());
}
if (endColumn == null || EMPTY.equals(endColumn)) {
// 默认获得第一行的列数
endColumn = xssfSheet.getRow(0).getPhysicalNumberOfCells();
map.put("endColumn", endColumn.toString());
}
// Read the Row
for (int rowNum = startLine - 1; rowNum < endLine; rowNum++) {
XSSFRow xssfRow = xssfSheet.getRow(rowNum);
if (xssfRow != null) {
for (int i = startColumn - 1; i < endColumn; i++) {
XSSFCell xc = xssfRow.getCell(i);
map.put(sheetNum + "-" + rowNum + "-" + i, getValue(xc));
}
}
}
}
// }
return map;
}
/**
* 读2003 xls Excel文件
*
* @param 文件路径
* @param startLine
* 开始行
* @param endLine
* 结束行
* @param startColumn
* 开始列
* @param endColumn
* 结束列
* @return
* @throws IOException
*/
public Map readXls(File file, Integer sheetNum, Integer startLine, Integer endLine,
Integer startColumn, Integer endColumn) throws IOException {
System.out.println(PROCESSING + file.getName());
InputStream is = new FileInputStream(file);
POIFSFileSystem fs = new POIFSFileSystem(is);
HSSFWorkbook hssfWorkbook = new HSSFWorkbook(fs);
Map map = new HashMap();
// Read the Sheet
// for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets();
// numSheet++) {
if (sheetNum == null || sheetNum.equals("")) {
sheetNum = 1;
map.put("sheetNum", sheetNum.toString());
}
HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(sheetNum - 1);
if (hssfSheet != null) {
if (startLine == null || EMPTY.equals(startLine)) {
startLine = 1;
map.put("startLine", startLine.toString());
}
if (endLine == null || EMPTY.equals(endLine)) {
endLine = hssfSheet.getLastRowNum() + 1;
map.put("endLine", endLine.toString());
}
if (startColumn == null || EMPTY.equals(startColumn)) {
startColumn = 1;
map.put("startColumn", startColumn.toString());
}
if (endColumn == null || EMPTY.equals(endColumn)) {
// 默认获得第一行的列数
endColumn = hssfSheet.getRow(0).getPhysicalNumberOfCells();
map.put("endColumn", endColumn.toString());
}
// Read the Row
for (int rowNum = startLine - 1; rowNum < endLine; rowNum++) {
HSSFRow hssfRow = hssfSheet.getRow(rowNum);
if (hssfRow != null) {
for (int i = startColumn - 1; i < endColumn; i++) {
// HSSFCell xc = hssfRow.getCell(i);
// System.out.println("xc=" + xc);
map.put(sheetNum + "-" + rowNum + "-" + i, getValue(hssfRow.getCell(i)));
}
}
}
}
// }
return map;
}
/**
* 获得后缀名
*
* @param path
* @return
*/
public String getPostfix(String path) {
if (path == null || EMPTY.equals(path.trim())) {
return EMPTY;
}
if (path.contains(POINT)) {
return path.substring(path.lastIndexOf(POINT) + 1, path.length());
}
return EMPTY;
}
@SuppressWarnings("static-access")
private String getValue(XSSFCell xssfRow) {
if (xssfRow.getCellType() == xssfRow.CELL_TYPE_BOOLEAN) {
return String.valueOf(xssfRow.getBooleanCellValue());
} else if (xssfRow.getCellType() == xssfRow.CELL_TYPE_NUMERIC) {
if (XSSFDateUtil.isCellDateFormatted(xssfRow)) {
return XSSFDateUtil.getJavaDate(xssfRow.getNumericCellValue()).toString();
} else {
HSSFDataFormatter dateFormatter=new HSSFDataFormatter();
String xcssfFormatted=dateFormatter.formatCellValue(xssfRow);
return xcssfFormatted;
}
} else {
return String.valueOf(xssfRow.getStringCellValue());
}
}
@SuppressWarnings("static-access")
private String getValue(HSSFCell hssfCell) {
if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
return String.valueOf(hssfCell.getBooleanCellValue());
} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
if (HSSFDateUtil.isCellDateFormatted(hssfCell)) {
return HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue()).toString();
} else {
HSSFDataFormatter dateFormatter=new HSSFDataFormatter();
String ceccFormatted=dateFormatter.formatCellValue(hssfCell);
return ceccFormatted;
}
} else {
return String.valueOf(hssfCell.getStringCellValue());
}
}
/**
* 删除文件
*
* @param path
* 文件路径
* @return
*/
public String deleteTemporaryFile(String path) {
if (path != null && !path.equals("")) {
File file = new File(path);
if (file.exists()) {
file.delete();
}
}
return "success";
}
public class XSSFDateUtil extends DateUtil{
protected static int absoluteDay(Calendar cal,boolean use1904windowing){
return DateUtil.absoluteDay(cal, use1904windowing);
}
}
数据源内容
4、通过jacob操作WORD,读取该书签的内容并进行替换,重新保存为PDF文档,核心代码如下:
package com.ecservice;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class PDFRead {
private static final int wdFormatPDF = 17;// word转PDF 格式
//Excel数据导入
private List readNameExcel(String path){
List NameLists=new ArrayList();
// 解析存储数据
parseExcelFile pef = new parseExcelFile();
try {
// 获得表数据中数据,
Integer sheetNum = 1;
Integer startLine = 0;
Integer endLine = null;
Integer startColumn = 1;
Integer endColumn = 1;
Map map = pef.readExcel(new File(path.trim()),
sheetNum, startLine, endLine, startColumn, endColumn);
if (map != null) {
sheetNum = (sheetNum == null ? Integer.parseInt((String) map.get("sheetNum")) : sheetNum);
startLine = (startLine == null ? Integer.parseInt((String) map.get("startLine")) : startLine);
endLine = (endLine == null ? Integer.parseInt((String) map.get("endLine")) : endLine);
startColumn = (startColumn == null ? Integer.parseInt((String) map.get("startColumn")) : startColumn);
endColumn = (endColumn == null ? Integer.parseInt((String) map.get("endColumn")) : endColumn);
// 存储数据
for (int i = startLine; i < endLine; i++) {
for(int j = startColumn-1; j < endColumn; j++){
String columdata = "";
if("*".equals(map.get(sheetNum + "-" + i + "-" + j))){
columdata = "0";
}else{
columdata = map.get(sheetNum + "-" + i + "-" + j).trim();
}
NameLists.add(columdata);
}
}
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
return NameLists;
}
public static void main(String[] args) {
ComThread.InitSTA();
List nameList=new PDFRead().readNameExcel("c://1.xlsx");
if(nameList!=null){
for (int k = 0; k < nameList.size(); k++) {
// 要保存的目标文件
String tpFile = "";
// 启动word,生成一个ActivexComponent对象
ActiveXComponent app = new ActiveXComponent("Word.Application");
// 要转换的word文件
String inFile = "C://1.doc";
// 要保存的目标文件
tpFile = "C://1/" + nameList.get(k) + ".pdf";
File fileDir=new File("C://1");
if(!fileDir.exists()){
fileDir.mkdirs();
fileDir.setWritable(true);
}
app.setProperty("Visible", false);
Dispatch docs = app.getProperty("Documents").toDispatch();
Dispatch doc = Dispatch.call(docs, //
"Open", //
inFile, // FileName
false, // ConfirmConversions
true // ReadOnly
).toDispatch();
// Dispatch activeDocument=app.getProperty("ActiveDocument").toDispatch();
Dispatch bookMarks = app.call(doc, "Bookmarks").toDispatch();
int bCount = Dispatch.get(bookMarks, "Count").getInt(); // 获取书签数
// 将书签列表存放到list + map 结构中
for (int i = 1; i <= bCount; i++) {
// Map bookMark = new HashMap(); //创建Map()
Dispatch items = Dispatch.call(bookMarks, "Item", i).toDispatch();
String bookMarkKey = String.valueOf(Dispatch.get(items, "Name").getString()).replaceAll("null", ""); // 读取书签命名
Dispatch range = Dispatch.get(items, "Range").toDispatch();
String bookMarkValue = String.valueOf(Dispatch.get(range, "Text").getString()).replaceAll("null", ""); // 读取书签文本
String MarkKey = bookMarkKey;
String MarkValue = bookMarkValue;
// 书签名并替换的内容
if (MarkKey.equals("xm"))// 书签名为xm
{
MarkValue = nameList.get(k); // 该xm书签处插入张三;
}
Dispatch.put(range, "Text", new Variant(MarkValue));
// 通过打印查看便于debug
System.out.println(bookMarkValue);
System.out.println(MarkValue);
// 保存文件
Dispatch.call(doc, //
"SaveAs", //
tpFile, // FileName
wdFormatPDF);
}
try {
Variant f = new Variant(false);
Dispatch.call(doc, "Close", f);
} catch (Exception e) {
e.printStackTrace();
} finally {
app.invoke("Quit", new Variant[] {});
ComThread.Release();
}
}
System.out.println("转化完成......");
}else{
System.out.println("读取excel失败!");
}
}
}
5、测试结果:
邀请函内容就这么愉快的替换掉啦
Ending!
PS:写的第一篇博文,有什么不足之处欢迎指正!