1. 程式人生 > 其它 >匯出Word工具類(根據資料動態生成並跨列)

匯出Word工具類(根據資料動態生成並跨列)

package com.ksource.modules.common;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.util.JSONTokener;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

/**
 * @author dxy
 *
 */
@Component
public class ExportWordUtil {

	public void createTable(String name, JSONArray json, HttpServletRequest request, HttpServletResponse response) throws Exception {
		XWPFDocument xdoc = new XWPFDocument();
		XWPFParagraph xp = xdoc.createParagraph();
		xp.setSpacingBefore(0);
		XWPFRun r = xp.createRun();
		r.setText(name+"查詢資訊");
		r.setFontFamily("宋體");
		r.setFontSize(18);
		r.setTextPosition(10);
		r.setBold(true);
		r.addBreak(); // 換行
		xp.setAlignment(ParagraphAlignment.CENTER);

		int sign = 0;
		for(int i = 0; i < json.size(); i++){
			JSONObject jsonObject = JSONObject.fromObject(json.get(i).toString());
			if ("1".equals(jsonObject.get("flag").toString())){
				sign = ++sign;
				xdoc.createParagraph();
				XWPFParagraph xp1 = xdoc.createParagraph();
				XWPFRun r1 = xp1.createRun();
				r1.setText((sign) +"."+ jsonObject.get("resourceName").toString());
				r1.setFontFamily("宋體");
				r1.setFontSize(16);
				r1.setBold(true);
				r1.setTextPosition(10);
				//r.addBreak(); // 換行
				xp1.setAlignment(ParagraphAlignment.LEFT);
				if (jsonObject.get("result") != null){
					int index = 0;
					JSONObject resultJsonObject = JSONObject.fromObject(jsonObject.get("result").toString());
					for(Object key : resultJsonObject.keySet()){
						String flag = parseJsonFormat(key.toString(),resultJsonObject.get(key).toString());
						System.out.println(resultJsonObject.get(key).toString());
						System.out.println(flag);
						writeDoc(xdoc,(sign)+"."+(++index),key.toString(),resultJsonObject.get(key).toString(),flag);
					}
				}
			}
		}
		downloadWord(xdoc,request,response);
	}

	private void writeDoc(XWPFDocument xdoc, String index, String key, String value, String flag){
		xdoc.createParagraph();
		XWPFParagraph xp = xdoc.createParagraph();
		XWPFRun r = xp.createRun();
		r.setText(index +"."+ key);
		r.setFontFamily("宋體");
		r.setFontSize(14);
		r.setBold(true);
		r.setTextPosition(10);
		//r.addBreak(); // 換行
		xp.setAlignment(ParagraphAlignment.LEFT);
		if("1".equals(flag)){
			getDetail(xdoc,value);
		}else if("2".equals(flag)){
			getList(xdoc,value);
		}else if("3".equals(flag)){
			getDetailList(xdoc,value);
		}
	}

	/**
	 * 獲取詳情
	 * @param xdoc
	 * @param value
	 */
	public void getDetail(XWPFDocument xdoc, String value){
		xdoc.createParagraph();
		int keyCount = 0;
		JSONObject valueJsonObject = JSONObject.fromObject(value);
		List list = new ArrayList();
		for(Object k : valueJsonObject.keySet()){
			++keyCount;
			list.add(k.toString());
			list.add(valueJsonObject.get(k).toString());
		}
		int fromCellIndex = keyCount*2 % 6;
		Integer row_total_count = (keyCount*2%6 == 0) ? keyCount*2/6 : (keyCount*2/6 + 1);
		Integer col_total_count = 6; // 表格最多的列數
		if(keyCount * 2 < 6){
			col_total_count = keyCount * 2;
		}
		XWPFTable xTable = xdoc.createTable();
		CTTbl ttbl = xTable.getCTTbl();
		CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
		CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
		tblWidth.setW(new BigInteger("9072"));
		tblWidth.setType(STTblWidth.DXA);
		for (int i = 0; i < row_total_count; i++) {
			XWPFTableRow row = xTable.insertNewTableRow(i);
			row.setHeight(450);
			int t = i*col_total_count;
			for (int j = 0; j < col_total_count; j++) {
				XWPFTableCell cell = row.createCell();
				XWPFParagraph p = cell.addParagraph();
				p.setAlignment(ParagraphAlignment.CENTER);
				p.setSpacingBefore(100);
				XWPFRun xRun = p.createRun();
				xRun.setFontSize(9);
				if ((j+t) < list.size()){
					if(j % 2 == 0){
						xRun.setBold(true);//是否粗體
						cell.setColor("f0f7ff");
					}
					if(!"".equals(list.get(j+t).toString())){
						xRun.setText(list.get(j+t).toString());
					}else{
						xRun.setText("暫無");
					}
				}else if(i == row_total_count - 1 && j == col_total_count - 1){
					mergeCellsHorizontal(xTable,row_total_count-1,col_total_count,fromCellIndex-1,col_total_count-1);
				}
			}
		}
		xTable.removeRow(row_total_count);
	}

	/**
	 * 獲取列表
	 * @param xdoc
	 * @param value
	 */
	public void getList(XWPFDocument xdoc, String value){
		JSONArray valueJsonArray = JSONArray.fromObject(value);
		for (int i = 0; i < valueJsonArray.size(); i++){
			getDetail(xdoc,valueJsonArray.get(i).toString());
		}
	}

	/**
	 * 獲取詳情和列表
	 * @param xdoc
	 * @param value
	 */
	public void getDetailList(XWPFDocument xdoc, String value){
		JSONObject valueJsonObject = JSONObject.fromObject(value);
		for(Object k : valueJsonObject.keySet()){
			String flag = parseJsonFormat(k.toString(),valueJsonObject.get(k).toString());
			if("1".equals(flag)){
				getDetail(xdoc,valueJsonObject.get(k).toString());
			}else if("2".equals(flag)){
				getList(xdoc,valueJsonObject.get(k).toString());
			}
		}
	}

	/**
	 * 判斷json格式
	 * @param key
	 * @param value
	 * @return
	 */
	public String parseJsonFormat(String key, String value){
		//當flag=1時json格式為詳情,當flag=2時json格式為列表,當flag=3時json格式為詳情+列表
		String flag = "";
		Object json = new JSONTokener(value).nextValue();
		if(json instanceof JSONObject){
			JSONObject jsonObject = (JSONObject)json;
			for(Object k : jsonObject.keySet()){
				boolean isJSON = isJSON(jsonObject.get(k).toString());
				if(isJSON){
					flag = "3";
					break;
				}else{
					flag = "1";
				}
			}
		}else if (json instanceof JSONArray){
			JSONArray jsonArray = (JSONArray)json;
			flag = "2";
		}
		return flag;
	}

	/**
	 * 判斷是否為json
	 * @param str
	 * @return
	 */
	public boolean isJSON(String str) {
		boolean result = false;
		try {
			Object obj = JSONObject.fromObject(str);
			result = true;
		} catch (Exception e) {
			result=false;
		}
		return result;
	}

	/**
	 * 設定表頭內容
	 * @param cell
	 * @param text
	 * @param bgcolor
	 * @param width
	 */
	private static void setCellText(XWPFDocument xdoc, XWPFTableCell cell,
									String text, String bgcolor, int width) {
		CTTc cttc = cell.getCTTc();
		CTTcPr cellPr = cttc.addNewTcPr();
		cellPr.addNewTcW().setW(BigInteger.valueOf(width));
		XWPFParagraph paragraph = cell.getParagraphs().get(0);
		paragraph.setAlignment(ParagraphAlignment.CENTER); //設定表頭單元格居中
		XWPFRun run  = paragraph.createRun();
		run.setFontFamily("仿宋_GB2312");
		run.setFontSize(16); //設定表頭單元格字號
		//run.setBold(true); //設定表頭單元格加粗
		run.setText(text);
	}

	/**
	 * 設定列寬
	 *
	 * @param index
	 * @return
	 */
	private static int getCellWidth(int index) {
		int cwidth = 1000;
		if (index == 0) {
			cwidth = 1000;
		} else if (index == 1) {
			cwidth = 2100;
		} else if (index == 2) {
			cwidth = 3200;
		} else if (index == 3) {
			cwidth = 2100;
		}
		return cwidth;
	}

	/**
  * 跨列合併
  * @param table
  * @param row  所合併的行
  * @param fromCell  起始列
  * @param toCell  終止列
  */
	public void mergeCellsHorizontal(XWPFTable table, int row, int colNum, int fromCell, int toCell) {
		table.getRow(row).getCell(fromCell).getCTTc().addNewTcPr().addNewTcW()
				.setW(BigInteger.valueOf((9072 / colNum) * (toCell - fromCell + 1)));
		for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
			XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
			if ( cellIndex == fromCell ) {
				// The first merged cell is set with RESTART merge value 
				cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
			} else {
				// Cells which join (merge) the first one, are set with CONTINUE 
				cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
			}
		}
	}

	/**
	 * 跨行合併
	 *
	 * @param table
	 * @param col
	 * @param fromRow
	 * @param toRow
	 */
	public static void mergeCellsVertically(XWPFTable table, int col,
											int fromRow, int toRow) {
		for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
			XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
			if (rowIndex == fromRow) {
				// The first merged cell is set with RESTART merge value
				cell.getCTTc().addNewTcPr().addNewVMerge()
						.setVal(STMerge.RESTART);
			} else {
				// Cells which join (merge) the first one, are set with CONTINUE
				cell.getCTTc().addNewTcPr().addNewVMerge()
						.setVal(STMerge.CONTINUE);
			}
		}
	}

	/**
	 * 將檔案轉換成byte陣列
	 * @return
	 */
	public byte[] fileToByte(File file){
		byte[] buffer = null;
		try
		{
			FileInputStream fis = new FileInputStream(file);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			byte[] b = new byte[1024];
			int n;
			while ((n = fis.read(b)) != -1)
			{
				bos.write(b, 0, n);
			}
			fis.close();
			bos.close();
			buffer = bos.toByteArray();
		}catch (FileNotFoundException e){
			e.printStackTrace();
		}catch (IOException e){
			e.printStackTrace();
		}
		return buffer;
	}

	/**
	 * 下載
	 * @param xdoc
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	public static void downloadWord(XWPFDocument xdoc, HttpServletRequest request, HttpServletResponse response) throws Exception {
		response.setCharacterEncoding("UTF-8");
		//response.setHeader("Content-disposition", "attachment;filename=" + fileName);
		response.setContentType("application/force-download");// 設定強制下載不開啟
		response.setHeader("Content-disposition", "attachment");
		//重新整理緩衝
		response.flushBuffer();
		OutputStream ouputStream = response.getOutputStream();
		//將word寫入到response的輸出流中,供頁面下載該Excel檔案
		xdoc.write(ouputStream);
		ouputStream.flush();
		ouputStream.close();
	}
}