需求:
現有一個excel文檔,該文檔從第三行開始,每一行代表一個化石及其相關的登記資料,如圖1,現在需要將每一行數據的內容,填寫到對應的word文檔中,並將入庫照片編號對應的照片插入對應位置,如圖2,最後要求不能生成單個的word文檔,因爲文檔個數多了,不方便整理和打印,需要合併成一個或者多個;
圖1:
圖2:
實現思路:
Java語言利用POI讀取excel文檔,利用Freemarker建立word模板(帶圖片),循環讀取excel每一行數據並生成單個word文檔,再利用POI合併成一個word文檔。
實現過程:
一、準備模板:參考博客園文章Java 用Freemarker完美導出word文檔(帶圖片)
1、word原件用eclipse或者其他編輯器如Firstobject free XML editor打開;
2、 把需要動態修改的內容替換成********(爲了後面方便查找和替換),如果有圖片,儘量選擇較小的圖片幾十K左右,並調整好位置(導入圖片時,不管什麼尺寸的圖片,都會按照現在固定好的格式大小及位置導入,也就是會出現圖片被拉伸變形,如果沒有對應的圖片,圖片位置會顯示如下圖);
3、另存爲,選擇保存類型Word 2003 XML 文檔(*.xml)【這裏說一下爲什麼用Microsoft Office Word打開且要保存爲Word 2003XML,本人親測,用WPS找不到Word 2003XML選項,如果保存爲Word XML,會有兼容問題,避免出現導出的word文檔不能用Word 2003打開的問題】,保存的文件名不要是中文;
4、用Firstobject free XML editor打開文件,選擇Tools下的Indent【或者按快捷鍵F8】格式化文件內容。左邊是文檔結構,右邊是文檔內容;
5、 將文檔內容中需要動態修改內容的地方,換成freemarker的標識。其實就是Map<String, Object>中key,如${landName}; (注意Map中不能沒有對應的key,否則會報錯,沒有內容的話,value放個空字符串就好了)
6、在加入了圖片佔位的地方,會看到一片base64編碼後的代碼,把base64替換成${image},也就是Map<String, Object>中key,值必須要處理成base64;
代碼如:<w:binData w:name="wordml://自定義.png" xml:space="preserve">${image}</w:binData>
注意:“>${image}<”這尖括號中間不能加任何其他的諸如空格,tab,換行等符號。
如果需要循環,則使用:<#list maps as map></#list> maps是Map<String, Object>中key,值爲數組,map爲自定義;
7、標識替換完之後,模板就弄完了,另存爲.ftl後綴文件即可。注意:一定不要用word打開ftl模板文件,否則xml內容會發生變化,導致前面的工作白做了。
二、讀取excel---生成word文檔---合併word文檔(源碼下載)
小提示:
1、word前後格式要一致,這裏代碼可能不兼容doc,所以word原文檔先另存爲docx格式的,後續生成、合併等都要使用docx;
2、excel讀取中,每一行的讀取時,不要跳過空格單元格,因爲向word中寫入時,是按照excel中的位置讀取的內容;
3、excel讀取時,注意框線,有的話,最好是有內容的行列同意都加框線,尤其注意最後一列,缺少框線時讀取會有問題;
主程序:
package e2w;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import sun.misc.BASE64Encoder;
/**
* 讀取excel文件,把每一行轉換爲一個word文檔數據
*
* @author 15730
*
*/
public class MainOO {
public static int qishibianhao;
public static File file;
public static String pic_url;
public static void main(String[] args) {
Boolean excel_is_exist=false;
Boolean num_is_right=false;
Boolean pic_url_is_right=false;
while(true){
if(excel_is_exist==false){
Scanner s = new Scanner(System.in);
System.out.println("請輸入excel文檔完整路徑,如:C:/Users/15730/Desktop/excel2word/新建 XLS 工作表 - 副本.xls,並按回車鍵");
String url = s.nextLine();
file = new File(url);
if(!file.exists()){
System.out.println("您輸入的文檔不存在!");
continue;
}else{
excel_is_exist=true;
}
}
if(num_is_right==false){
Scanner s = new Scanner(System.in);
System.out.println("請輸入文檔起始編號,1-9999之間的整數,如果輸入1,則編號從M1-0001開始,如果輸入123,則編號從M1-0123開始,輸入完成後請按回車鍵");
int num = s.nextInt();
if(num>0&&num<10000){
qishibianhao=num;//記錄初始編號
num_is_right=true;
}else{
System.out.println("您輸入的內容錯誤!");
continue;
}
}
//圖片所在文件夾
if(pic_url_is_right==false){
Scanner s = new Scanner(System.in);
System.out.println("請輸入圖片存儲的完整文件夾名稱,如:C:/Users/15730/Desktop/excel2word/tupian/,並按回車鍵");
String url = s.nextLine();
File file = new File(url);
if(!file.exists()){
System.out.println("您輸入的文件夾錯誤!");
continue;
}else{
if(file.isDirectory()){
pic_url=url;
pic_url_is_right=true;
}else{
System.out.println("您輸入的文件夾錯誤!");
continue;
}
}
}
//全部準備好後,開始執行
if(excel_is_exist==true&&num_is_right==true&&pic_url_is_right==true){
break;
}
}
try {
if(file==null){
System.out.println("文檔不存在");
return;
}
List<List<Object>> list_hang = CreatAndReadExcel.readExcel(file);
System.out.println("---------------------------------------------");
System.out.println("本文檔行數:"+list_hang.size());
for (int i = 0; i < list_hang.size(); i++) {
if (i < 2) {
continue;
}
String biaoTouBianHao = getBiaoTouBianHao(qishibianhao++);// 表頭編號
List<Object> list_lie = list_hang.get(i);
// System.out.println(list_lie.size());
// System.out.println("---------------------------------------------");
// for(int j=0;j<list_lie.size();j++){
// System.out.println(list_lie.get(j));
// }
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("bianhao", biaoTouBianHao);
// String xuHao = list_lie.get(0).toString();//需要,word用不到
String quDuanHao = list_lie.get(1).toString();// 區段號
map.put("quDuanHao", quDuanHao);
String yeWaiBianHao = list_lie.get(2).toString();// 野外原始編號
map.put("yeWaiBianHao", yeWaiBianHao);
String huaShiBianHao = list_lie.get(3).toString();// 化石編號
map.put("huaShiBianHao", huaShiBianHao);
String huaShiLeiBie = list_lie.get(4).toString();// 化石類別
map.put("huaShiLeiBie", huaShiLeiBie);
String buWeiMingCheng = list_lie.get(5).toString();// 部位名稱
map.put("buWeiMingCheng", buWeiMingCheng);
String diCeng = list_lie.get(6).toString();// 地層
map.put("diCeng", diCeng);
String chanDi = list_lie.get(7).toString();// 產 地
map.put("chanDi", chanDi);
// String ruKuShiJian = list_lie.get(8).toString();
// //入庫時間,此字段不需要
String huaShiJiBenMiaoShu = list_lie.get(9).toString();// 化石基本描述
map.put("huaShiJiBenMiaoShu", huaShiJiBenMiaoShu);
String ruKuZhaoPianBianHao = list_lie.get(10).toString();// 入庫照片編號,根據圖片名稱,查找圖片並插入word
/**
* 臨時目錄
*/
String src=pic_url+ruKuZhaoPianBianHao+".jpg";
// System.out.println(" ");
// System.out.println(" ---- "+src);
File pic = new File(src);
if(pic.exists()){
map.put("image", getImageBase(src));
}else{
map.put("image", "");
}
// 以下三種保存方式,每個只有一種,前兩種需要拆分字符串
String huoJiaBaoCun = list_lie.get(11).toString();// 貨架保存
// (架-列-層)
String MiFengGuiBaoCun = list_lie.get(12).toString();// 密集櫃保存
// (架-列-層)
String shaCaoBaoCun = list_lie.get(13).toString();// 沙槽保存
// System.out.println("區段號 : " + quDuanHao);
// System.out.println("野外原始編號 : " + yeWaiBianHao);
// System.out.println("化石編號 : " + huaShiBianHao);
// System.out.println("化石類別 : " + huaShiLeiBie);
// System.out.println("部位名稱 : " + buWeiMingCheng);
// System.out.println("地層 : " + diCeng);
// System.out.println("產地 : " + chanDi);
// System.out.println("化石基本描述 : " + huaShiJiBenMiaoShu);
// System.out.println("入庫照片編號 : " + ruKuZhaoPianBianHao);
// System.out.println("貨架保存 (架-列-層) : "+huoJiaBaoCun);
// System.out.println("密集櫃保存 (架-列-層) : "+MiFengGuiBaoCun);
if (huoJiaBaoCun != "") {//貨架保存
String[] str = huoJiaBaoCun.split("-");
String huoJiaBaoCun_jiahao = str[0];
String huoJiaBaoCun_liehao = str[1];
String huoJiaBaoCun_cenghao = str[2];
// System.out.println("貨架保存 (架) : "
// + huoJiaBaoCun_jiahao);
// System.out.println("貨架保存 (列) : "
// + huoJiaBaoCun_liehao);
// System.out.println("貨架保存 (層) : "
// + huoJiaBaoCun_cenghao);
map.put("huoJiaBaoCun_jiahao", huoJiaBaoCun_jiahao);
map.put("huoJiaBaoCun_liehao", huoJiaBaoCun_liehao);
map.put("huoJiaBaoCun_cenghao", huoJiaBaoCun_cenghao);
map.put("MiFengGuiBaoCun_jiahao",
"");
map.put("MiFengGuiBaoCun_liehao",
"");
map.put("MiFengGuiBaoCun_cenghao",
"");
map.put("shaCaoBaoCun", "");
} else if (MiFengGuiBaoCun != "") {//密集櫃保存
String[] str = MiFengGuiBaoCun.split("-");
String MiFengGuiBaoCun_jiahao = str[0];
String MiFengGuiBaoCun_liehao = str[1];
String MiFengGuiBaoCun_cenghao = str[2];
// System.out.println("密集櫃保存 (架) : "
// + MiFengGuiBaoCun_jiahao);
// System.out.println("密集櫃保存 (列) : "
// + MiFengGuiBaoCun_liehao);
// System.out.println("密集櫃保存 (層) : "
// + MiFengGuiBaoCun_cenghao);
map.put("MiFengGuiBaoCun_jiahao",
MiFengGuiBaoCun_jiahao);
map.put("MiFengGuiBaoCun_liehao",
MiFengGuiBaoCun_liehao);
map.put("MiFengGuiBaoCun_cenghao",
MiFengGuiBaoCun_cenghao);
map.put("huoJiaBaoCun_jiahao", "");
map.put("huoJiaBaoCun_liehao", "");
map.put("huoJiaBaoCun_cenghao", "");
map.put("shaCaoBaoCun", "");
} else if (shaCaoBaoCun != "") {//沙槽保存
// System.out.println("沙槽保存 : " + shaCaoBaoCun);
map.put("shaCaoBaoCun", shaCaoBaoCun);
map.put("MiFengGuiBaoCun_jiahao",
"");
map.put("MiFengGuiBaoCun_liehao",
"");
map.put("MiFengGuiBaoCun_cenghao",
"");
map.put("huoJiaBaoCun_jiahao", "");
map.put("huoJiaBaoCun_liehao", "");
map.put("huoJiaBaoCun_cenghao", "");
} else {
System.out.println("第"+(i+1)+"行存在格式問題,請注意檢查是否存在少邊框或者三種存儲方式都爲空的情況");
}
WordUtils.exportWord(map, biaoTouBianHao, "map.ftl");
}
}
} catch (IOException e) {
e.printStackTrace();
}
// WordUtils.exportMillCe。rtificateWord(getRequest(),getResponse(),map,"方案","sellPlan.ftl");
}
public static String getBiaoTouBianHao(int i){
String biaoTouBianHao = "M1-";//"M1-0001"
String num = new Integer(i).toString();
String temp="";
switch (num.length()) {
case 1:
temp = "000";
break;
case 2:
temp = "00";
break;
case 3:
temp = "0";
break;
case 4:
temp = "";
break;
default:
break;
}
return biaoTouBianHao+temp+num;
}
//獲得圖片的base64碼
@SuppressWarnings("deprecation")
public static String getImageBase(String src) {
if(src==null||src==""){
return "";
}
File file = new File(src);
if(!file.exists()) {
return "";
}
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
}
excel操作:
package e2w;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* 可以從http://poi.apache.org/ 這裏下載到POI的jar�?POI 創建和讀�?003-2007版本Excel文件
*
*/
public class CreatAndReadExcel {
public static void main(String[] args) throws Exception {
// creat2003Excel();// 創建2007版Excel文件
// creat2007Excel();// 創建2003版Excel文件
// 讀取2003Excel文件
String path2003 = System.getProperty("user.dir")
+ System.getProperty("file.separator") + "style_2003.xls";// 獲取項目文件路徑
// +2003版文件名
System.out.println("路徑:" + path2003);
File f2003 = new File(path2003);
try {
readExcel(f2003);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// //讀取2007Excel文件
// String path2007 = System.getProperty("user.dir")
// + System.getProperty("file.separator") + "style_2007.xlsx";//
// 獲取項目文件路徑+2007版文件名
// // System.out.println("路徑�? + path2007);
// File f2007 = new File(path2007);
// try {
// readExcel(f2007);
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
/**
* 創建2007版Excel文件
*
* @throws FileNotFoundException
* @throws IOException
*/
private static void creat2007Excel() throws FileNotFoundException,
IOException {
// HSSFWorkbook workBook = new HSSFWorkbook();// 創建 �?��excel文檔對象
XSSFWorkbook workBook = new XSSFWorkbook();
XSSFSheet sheet = workBook.createSheet();// 創建�?��工作薄對�?
sheet.setColumnWidth(0, 10000);// 設置第二列的寬度�?
XSSFRow row = sheet.createRow(1);// 創建�?��行對�?
row.setHeightInPoints(23);// 設置行高23像素
XSSFCellStyle style = workBook.createCellStyle();// 創建樣式對象
// 設置字體
XSSFFont font = workBook.createFont();// 創建字體對象
font.setFontHeightInPoints((short) 15);// 設置字體大小
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 設置粗體
font.setFontName("黑體");// 設置爲黑體字
style.setFont(font);// 將字體加入到樣式對象
// 設置對齊方式
style.setAlignment(HSSFCellStyle.ALIGN_CENTER_SELECTION);// 水平居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
// 設置邊框
style.setBorderTop(HSSFCellStyle.BORDER_THICK);// 頂部邊框粗線
style.setTopBorderColor(HSSFColor.RED.index);// 設置爲紅�?
style.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);// 底部邊框雙線
style.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);// 左邊邊框
style.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);// 右邊邊框
// 格式化日�?
style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
XSSFCell cell = row.createCell(1);// 創建單元�?
cell.setCellValue(new Date());// 寫入當前日期
cell.setCellStyle(style);// 應用樣式對象
// 文件輸出�?
FileOutputStream os = new FileOutputStream("style_2007.xlsx");
workBook.write(os);// 將文檔對象寫入文件輸出流
os.close();// 關閉文件輸出�?
System.out.println("創建成功 office 2007 excel");
}
/**
* 創建2003版本的Excel文件
*/
public static void creat2003Excel(String path)
throws FileNotFoundException, IOException {
HSSFWorkbook workBook = new HSSFWorkbook();// 創建 一個excel文檔對象
HSSFSheet sheet = workBook.createSheet();// 創建 一個工作薄對象?
sheet.setColumnWidth(0, 3000);// 設置第1列的寬度
sheet.setColumnWidth(1, 5000);// 設置第2列的寬度
sheet.setColumnWidth(2, 3000);// 設置第3列的寬度
// HSSFRow row = sheet.createRow(1);// 創建一個行對象
// row.setHeightInPoints(23);// 設置行高23像素
// HSSFCellStyle style = workBook.createCellStyle();// 創建樣式對象
// 設置字體
// HSSFFont font = workBook.createFont();// 創建字體對象
// font.setFontHeightInPoints((short) 15);// 設置字體大小
// font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 設置粗體
// font.setFontName("黑體");// 設置爲黑體字
// style.setFont(font);// 將字體加入到樣式對象
// 設置對齊方式
// style.setAlignment(HSSFCellStyle.ALIGN_CENTER_SELECTION);// 水平居中
//
// style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
// 設置邊框
// style.setBorderTop(HSSFCellStyle.BORDER_THICK);// 頂部邊框粗線
//
// style.setTopBorderColor(HSSFColor.RED.index);// 設置爲紅�?
//
// style.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);// 底部邊框雙線
//
// style.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);// 左邊邊框
//
// style.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);// 右邊邊框
// 格式化日�?
// style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
//
// HSSFCell cell = row.createCell(1);// 創建單元�?
// cell.setCellValue(new Date());// 寫入當前日期
// cell.setCellStyle(style);// 應用樣式對象
// 文件輸出�?
FileOutputStream os = new FileOutputStream(path);
workBook.write(os);// 將文檔對象寫入文件輸出流
os.close();// 關閉文件輸出�?
// System.out.println("創建成功 office 2003 excel");
}
/**
* 對外提供讀取excel 的方�?
*/
public static List<List<Object>> readExcel(File file) throws IOException {
String fileName = file.getName();
String extension = fileName.lastIndexOf(".") == -1 ? "" : fileName
.substring(fileName.lastIndexOf(".") + 1);
if ("xls".equals(extension)) {
return read2003Excel(file);
} /*
* else if ("xlsx".equals(extension)) { return read2007Excel(file); }
*/else {
throw new IOException("不支持的文件類型");
}
}
/**
* 讀取 office 2003 excel
*
* @throws IOException
* @throws FileNotFoundException
*/
private static List<List<Object>> read2003Excel(File file)
throws IOException {
List<List<Object>> list = new LinkedList<List<Object>>();
HSSFWorkbook hwb = new HSSFWorkbook(new FileInputStream(file));
HSSFSheet sheet = hwb.getSheetAt(0);
Object value = null;
HSSFRow row = null;
HSSFCell cell = null;
System.out.println("讀取office 2003 excel內容如下: ");
for (int i = sheet.getFirstRowNum(); i <= sheet
.getPhysicalNumberOfRows(); i++) {
row = sheet.getRow(i);
if (row == null) {
continue;
}
List<Object> linked = new LinkedList<Object>();
for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {
cell = row.getCell(j);
if (cell == null) {
continue;
}
DecimalFormat df = new DecimalFormat("0");// 格式�?number String
// 字符
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");// 格式化日期字符串
DecimalFormat nf = new DecimalFormat("0.00");// 格式化數�?
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_STRING:
// System.out.println(i + "�? + j + " �?is String type");
value = cell.getStringCellValue();
System.out.print(" " + value + " ");
break;
case XSSFCell.CELL_TYPE_NUMERIC:
// System.out.println(i + "�? + j
// + " �?is Number type ; DateFormt:"
// + cell.getCellStyle().getDataFormatString());
if ("@".equals(cell.getCellStyle().getDataFormatString())) {
value = df.format(cell.getNumericCellValue());
} else if ("General".equals(cell.getCellStyle()
.getDataFormatString())) {
value = nf.format(cell.getNumericCellValue());
} else {
value = sdf.format(HSSFDateUtil.getJavaDate(cell
.getNumericCellValue()));
}
System.out.print(" " + value + " ");
break;
case XSSFCell.CELL_TYPE_BOOLEAN:
// System.out.println(i + "�? + j + " �?is Boolean type");
value = cell.getBooleanCellValue();
System.out.print(" " + value + " ");
break;
case XSSFCell.CELL_TYPE_BLANK:
// System.out.println(i + "�? + j + " �?is Blank type");
value = "";
System.out.print(" " + value + " ");
break;
default:
// System.out.println(i + "�? + j + " �?is default type");
value = cell.toString();
System.out.print(" " + value + " ");
}
/**
* 當一行中的某單元格是空着(不是打了空格)的時候,同樣加入到list中,用標題行的列數控制讀取的單元格數
* 2019年3月18日
*
*/
// if (value == null || "".equals(value)) {
// continue;
// }
linked.add(value);
}
System.out.println("");
list.add(linked);
}
return list;
}
/**
* 讀取Office 2007 excel
*/
/*
* private static List<List<Object>> read2007Excel(File file) throws
* IOException {
*
* List<List<Object>> list = new LinkedList<List<Object>>(); // String path
* = System.getProperty("user.dir") + //
* System.getProperty("file.separator")+"dd.xlsx"; //
* System.out.println("路徑�?+path); // 構�? XSSFWorkbook 對象,strPath 傳入文件路徑
* XSSFWorkbook xwb = new XSSFWorkbook(new FileInputStream(file));
*
* // 讀取第一章表格內�? XSSFSheet sheet = xwb.getSheetAt(0); Object value = null;
* XSSFRow row = null; XSSFCell cell = null; System.out.println("讀取office
* 2007 excel內容如下�?); for (int i = sheet.getFirstRowNum(); i <= sheet
* .getPhysicalNumberOfRows(); i++) { row = sheet.getRow(i); if (row ==
* null) { continue; } List<Object> linked = new LinkedList<Object>(); for
* (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) { cell =
* row.getCell(j); if (cell == null) { continue; } DecimalFormat df = new
* DecimalFormat("0");// 格式�?number String // 字符 SimpleDateFormat sdf = new
* SimpleDateFormat( "yyyy-MM-dd HH:mm:ss");// 格式化日期字符串 DecimalFormat nf =
* new DecimalFormat("0.00");// 格式化數�?
*
* switch (cell.getCellType()) { case XSSFCell.CELL_TYPE_STRING: //
* System.out.println(i + "�? + j + " �?is String type"); value =
* cell.getStringCellValue(); System.out.print(" " + value + " "); break;
* case XSSFCell.CELL_TYPE_NUMERIC: // System.out.println(i + "�? + j // +
* " �?is Number type ; DateFormt:" // +
* cell.getCellStyle().getDataFormatString()); if
* ("@".equals(cell.getCellStyle().getDataFormatString())) { value =
* df.format(cell.getNumericCellValue());
*
* } else if ("General".equals(cell.getCellStyle() .getDataFormatString()))
* { value = nf.format(cell.getNumericCellValue()); } else { value =
* sdf.format(HSSFDateUtil.getJavaDate(cell .getNumericCellValue())); }
* System.out.print(" " + value + " "); break; case
* XSSFCell.CELL_TYPE_BOOLEAN: // System.out.println(i + "�? + j + " �?is
* Boolean type"); value = cell.getBooleanCellValue(); System.out.print(" "
* + value + " "); break; case XSSFCell.CELL_TYPE_BLANK: //
* System.out.println(i + "�? + j + " �?is Blank type"); value = ""; //
* System.out.println(value); break; default: // System.out.println(i +
* "�? + j + " �?is default type"); value = cell.toString();
* System.out.print(" " + value + " "); } if (value == null ||
* "".equals(value)) { continue; } linked.add(value); }
* System.out.println(""); list.add(linked); } return list; }
*/
}
word操作:
package e2w;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class WordUtils {
// 配置信息,代碼本身寫的還是很可讀的,就不過多註解了
private static Configuration configuration = null;
// 這裏注意的是利用WordUtils的類加載器動態獲得模板文件的位置
private static final String templateFolder = WordUtils.class
.getClassLoader().getResource("").getPath()
+ "templates/";
// private static final String templateFolder =
// "D:\\java_old\\workspace\\excel2Word\\bin\\templates";
static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
try {
configuration.setDirectoryForTemplateLoading(new File(
templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
}
private WordUtils() {
throw new AssertionError();
}
// public static void exportMillCertificateWord(HttpServletRequest request,
// HttpServletResponse response, Map map,String title,String ftlFile) throws
// IOException {
// Template freemarkerTemplate = configuration.getTemplate(ftlFile);
// File file = null;
// InputStream fin = null;
// ServletOutputStream out = null;
// try {
// // 調用工具類的createDoc方法生成Word文檔
// file = createDoc(map,freemarkerTemplate);
// fin = new FileInputStream(file);
//
// response.setCharacterEncoding("utf-8");
// response.setContentType("application/msword");
// // 設置瀏覽器以下載的方式處理該文件名
// String fileName = title+DateUtil.formatDateDetailTime(new Date()) +
// ".doc";
// response.setHeader("Content-Disposition", "attachment;filename="
// .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
//
// out = response.getOutputStream();
// byte[] buffer = new byte[512]; // 緩衝區
// int bytesToRead = -1;
// // 通過循環將讀入的Word文件的內容輸出到瀏覽器中
// while((bytesToRead = fin.read(buffer)) != -1) {
// out.write(buffer, 0, bytesToRead);
// }
// } finally {
// if(fin != null) fin.close();
// if(out != null) out.close();
// if(file != null) file.delete(); // 刪除臨時文件
// }
// }
private static File createDoc(Map<?, ?> dataMap, String title,
Template template) {
String fileName = title + ".docx";
File f = new File(fileName);
Template t = template;
try {
// 這個地方不能使用FileWriter因爲需要指定編碼類型否則生成的Word文檔會因爲有無法識別的編碼而無法打開
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
public static void exportWord(Map<?, ?> map, String title, String ftlFile)
throws IOException {
System.out.println("-------------------- " + templateFolder);
Template freemarkerTemplate = configuration.getTemplate(ftlFile);
// 調用工具類的createDoc方法生成Word文檔
File file = createDoc(map, title, freemarkerTemplate);
}
}
word合併:
package e2w;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
/**
* @author: Max
*
* @Date: 2018/6/8
*
* @name: 多個word文件合併,採用poi實現,兼容圖片的遷移
*
* @Description:
*/
public class MergeDoc {
public static void main (String[] args) throws Exception {
InputStream in1 = null;
InputStream in2 = null;
InputStream in3 = null;
OPCPackage src1Package = null;
OPCPackage src2Package = null;
OPCPackage src3Package = null;
OutputStream dest = new FileOutputStream("C:/Users/15730/Desktop/excel2word/merge123.docx");
try {
in1 = new FileInputStream("C:/Users/15730/Desktop/excel2word/M1-0001.docx");
in2 = new FileInputStream("C:/Users/15730/Desktop/excel2word/M1-0002.docx");
in3 = new FileInputStream("C:/Users/15730/Desktop/excel2word/M1-0003.docx");
src1Package = OPCPackage.open(in1);
src2Package = OPCPackage.open(in2);
src3Package = OPCPackage.open(in3);
} catch (Exception e) {
e.printStackTrace();
}
XWPFDocument src1Document = new XWPFDocument(src1Package);
XWPFDocument src2Document = new XWPFDocument(src2Package);
XWPFDocument src3Document = new XWPFDocument(src3Package);
appendBody(src1Document, src2Document);
appendBody(src1Document, src3Document);
src1Document.write(dest);
}
public static void appendBody(XWPFDocument src, XWPFDocument append) throws Exception {
CTBody src1Body = src.getDocument().getBody();
CTBody src2Body = append.getDocument().getBody();
List<XWPFPictureData> allPictures = append.getAllPictures();
// 記錄圖片合併前及合併後的ID
Map<String,String> map = new HashMap();
for (XWPFPictureData picture : allPictures) {
String before = append.getRelationId(picture);
//將原文檔中的圖片加入到目標文檔中
String after = src.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
map.put(before, after);
}
appendBody(src1Body, src2Body,map);
}
private static void appendBody(CTBody src, CTBody append,Map<String,String> map) throws Exception {
XmlOptions optionsOuter = new XmlOptions();
optionsOuter.setSaveOuter();
String appendString = append.xmlText(optionsOuter);
String srcString = src.xmlText();
String prefix = srcString.substring(0,srcString.indexOf(">")+1);
String mainPart = srcString.substring(srcString.indexOf(">")+1,srcString.lastIndexOf("<"));
String sufix = srcString.substring( srcString.lastIndexOf("<") );
String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<"));
if (map != null && !map.isEmpty()) {
//對xml字符串中圖片ID進行替換
for (Map.Entry<String, String> set : map.entrySet()) {
addPart = addPart.replace(set.getKey(), set.getValue());
}
}
//將兩個文檔的xml內容進行拼接
CTBody makeBody = CTBody.Factory.parse(prefix+mainPart+addPart+sufix);
src.set(makeBody);
}
}
後記:
在打包程序時,遇到了一些問題,見另外兩篇博客:
1、eclipse導出可運行jar包時,雙擊沒反應,命令行中jar命令運行報錯“**.jar中沒有主清單屬性”或者報錯“Error: Invalid or corrup jarfile **.jar。