package com.report;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
/**
 * POIDEMO工具类
 * @author yejia
 *
 */
public class PoiUtil {
	/**
	 * 替换文本内容
	 * @param doc
	 * @param dataMap
	 */
	public static void replaceText(XWPFDocument doc, Map dataMap) {
		Iterator<XWPFParagraph> iter = doc.getParagraphsIterator();
		while(iter.hasNext()) {
			XWPFParagraph paragraph = iter.next();
			try {
				// Add comments
				List<XWPFRun> runs = paragraph.getRuns();
				if(runs==null || runs.size()==0) continue;
				for (int i = 0; i < runs.size(); i++) {
					XWPFRun run = runs.get(i);
					String text = run.getText(0);
					if(text==null) continue;
					System.out.println("text="+text);
					if(dataMap.containsKey(text)) {
						//从dataMap中取出要替换的值，将run对象中的值重置为新值
						String newText = (String)dataMap.get(text);
						run.setText(newText,0);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
	}
	
	/**
	 * 添加图片
	 * 简单示例
	 * @param doc
	 * @param dataMap
	 */
	public static void addImage(CustomXWPFDocument doc, Map dataMap) {
		try {
			InputStream in = PoiUtil.class.getClass().getResourceAsStream("/resource/logo.gif");
			byte[] bytes = IOUtils.toByteArray(in); 
			//int picI = doc.addPicture(bytes, XWPFDocument.PICTURE_TYPE_JPEG);
			//doc.createPicture(picI, 128, 45);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 处理动态表格
	 * 默认取第二行第一列的标识
	 * @param table
	 * @param ctRow
	 * @param values 需要添加的数据
	 */
	public static void processDynamicTable(XWPFTable table, CTRow ctRow, List<String[]> values) {
		if(values==null || values.size()==0) return;
		for (Iterator<String[]> iterator = values.iterator(); iterator.hasNext();) {
			String[] value = iterator.next();
			XWPFTableRow newRow = new XWPFTableRow(ctRow,table);
			List<XWPFTableCell> cells = newRow.getTableCells();
			if(cells==null || cells.size()==0) return;
			for (int j = 0; j < cells.size(); j++) {
				XWPFTableCell cell = cells.get(j);
				cell.removeParagraph(0);
				if(j<=value.length) cell.setText(value[j]);
			}
			table.addRow(newRow);
		}
	}
	/**
	 * 处理表格
	 * @param doc
	 * @param dataMap
	 */
	public static void processTable(XWPFDocument doc, Map dataMap) {
		Iterator<XWPFTable> iter = doc.getTablesIterator();
		while(iter.hasNext()) {
			XWPFTable table = iter.next();
			List<XWPFTableRow> rows = table.getRows();
			if(rows==null || rows.size()==0) continue;
			CTRow ctRow = null;
			for (int i = 0; i < rows.size(); i++) {
				XWPFTableRow row = rows.get(i);
				ctRow = (CTRow)row.getCtRow().copy();
				List<XWPFTableCell> cells = row.getTableCells();
				if(cells==null || cells.size()==0) continue;
				//处理标致
				boolean sign = false;
				for (int j = 0; j < cells.size(); j++) {
					XWPFTableCell cell = cells.get(j);
					if(cell.getText()==null) continue;
					if(i==1 && j==0) {
						//取第二行第一列的值，再添加table.关键字之后与dataMap匹配，有则当动态表格处理
						String key = "table."+ cell.getText();
						if(dataMap.containsKey(key)) {
							List values = (List)dataMap.get(key);
							table.removeRow(1);
							processDynamicTable(table, ctRow, values);
							//更新处理标致
							sign = true;
							break;
						}
					}
					if(!cell.getText().startsWith("\\$") && cell.getText().endsWith("\\$")) continue;
					String key = cell.getText().replaceAll("\\$", "");
					if(dataMap.containsKey(key)) {
						cell.removeParagraph(0);
						String text = (String)dataMap.get(key);
						cell.setText(text);
					}
				}
				//如果已处理，则终止遍历
				if(sign) break;
			}
		}
	}
	
	/**
	 * 处理表格
	 * @param doc
	 * @param dataMap
	 */
	public static void replaceTableText(XWPFDocument doc, Map dataMap) {
		Iterator<XWPFTable> iter = doc.getTablesIterator();
		while(iter.hasNext()) {
			XWPFTable table = iter.next();
			List<XWPFTableRow> rows = table.getRows();
			if(rows==null || rows.size()==0) continue;
			CTRow ctRow = null;
			for (int i = 0; i < rows.size(); i++) {
				XWPFTableRow row = rows.get(i);
				//ctRow = (CTRow)row.getCtRow().copy();
				List<XWPFTableCell> cells = row.getTableCells();
				if(cells==null || cells.size()==0) continue;
				//处理标致
				for (int j = 0; j < cells.size(); j++) {
					XWPFTableCell cell = cells.get(j);
					if(cell.getText()==null) continue;
					String celltext = cell.getText();
					Set set = dataMap.keySet();
					String newstr = "";
					String oldstr = "";
					boolean replaceIS = false;
					for (Object mkey : set) {
                       oldstr = (String)mkey;
                       newstr = (String)dataMap.get(mkey);
					   //System.out.println("键:"+oldstr+"  值:"+newstr);
                       if(celltext.indexOf(oldstr,0) > -1){
                    	   //celltext = celltext.replaceAll(oldstr, newstr);
                    	   replaceIS = true;
                    	   break;//一个单元格只替换一个标志
                       }
					}
                    if(replaceIS){
                    	List<XWPFParagraph> paragraphList = cell.getParagraphs();
    					int nloop = paragraphList.size();
    					for(int n=0;n<nloop;n++){
    						XWPFParagraph paragraph = paragraphList.get(n);
    						String textstr = paragraph.getText();
    						//System.out.println("textstr="+textstr+", n="+Integer.toString(n));
    						if(textstr.indexOf(oldstr,0) > -1){
    							String tnewstr = textstr.replaceAll(oldstr, newstr);
    							cell.removeParagraph(n);// 感觉注释有些问题,这个好像只是删除单元格原有内容,而不是删掉整个段落
    	                    	XWPFParagraph newPara = new XWPFParagraph(cell.getCTTc().addNewP(), cell);
    	                    	newPara.setAlignment(ParagraphAlignment.RIGHT);
    	                    	XWPFRun run=newPara.createRun();
    	                    	//run.setUnderline(UnderlinePatterns.THICK);
    	                        run.setText(tnewstr);
    						}
    					}
                    }
				}
			}
		}
	}
}