Java語言利用POI讀取excel文檔,利用Freemarker建立word模板(帶圖片),excel每一行數據生成單個word文檔,再利用POI合併成一個word文檔

需求:

        現有一個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。

2、MANIFEST.MF文件詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章