package com.report;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jxl.CellType;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableIterator;
import org.apache.poi.hwpf.usermodel.TableRow;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;

import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.POIXMLDocument;  
import org.apache.poi.POIXMLTextExtractor;  
import org.apache.poi.hwpf.extractor.WordExtractor;  
import org.apache.poi.openxml4j.opc.OPCPackage;  
import org.apache.poi.xwpf.extractor.XWPFWordExtractor; 

public class PoiWordReport {
	public PoiWordReport() {
        super();
    }
	private static Map getDataMap() {
		Map dataMap = new HashMap();
		dataMap.put("companyName", "上海吉贝克信息技术有限公司");
		dataMap.put("address", "上海市杨浦区翔殷路1088号15层");
		dataMap.put("column1", "非动态表格第一列");
		dataMap.put("column2", "非动态表格第二列");
		dataMap.put("column3", "非动态表格第三列");
		dataMap.put("table.table1", getTable1Data());
		dataMap.put("table.table2", getTable2Data());
		
		dataMap.put("no1", "123");
		dataMap.put("node2", "eee");
		return dataMap;
	}
	private static List getTable1Data() {
		List list = new LinkedList();
		for (int i = 0; i < 4; i++) {
			list.add(new String[]{i+"行一列",i+"行二列",i+"行三列",i+"行四列"});
		}
		return list;
	}
	private static List getTable2Data() {
		List list = new LinkedList();
		for (int i = 0; i < 2; i++) {
			list.add(new String[]{i+"行一列",i+"行二列",i+"行三列",i+"行四列","",i+"abc6"});
		}
		return list;
	}
	/**
	public static void main(String[] args) {
		try {
			String path = System.getProperty("user.dir") + File.separator + "src/resource/";
			System.out.println("path="+path);
			OPCPackage pack = POIXMLDocument.openPackage(path+ "wordtest.docx");
			CustomXWPFDocument doc = new CustomXWPFDocument(pack);
			Map dataMap = getDataMap();
			PoiUtil.processTable(doc, dataMap);
			//PoiUtil.addImage(doc, dataMap);
			PoiUtil.replaceText(doc, dataMap);
			//注：此处可再继续扩展页眉和页脚的处理
			
			//将处理好的Word写到文件中
			FileOutputStream output = new FileOutputStream(path+"test_out1.docx");
			doc.write(output);
			output.flush();
			output.close();
			System.out.println("处理完成");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	**/
	
	public static void main2(String[] args) {
		try {
			String path = System.getProperty("user.dir") + File.separator + "src/resource/";
			OPCPackage pack = POIXMLDocument.openPackage(path+ "wordtest.docx");
			CustomXWPFDocument doc = new CustomXWPFDocument(pack);
			Map dataMap = getDataMap();
			PoiUtil.processTable(doc, dataMap);
			//PoiUtil.addImage(doc, dataMap);
			PoiUtil.replaceText(doc, dataMap);
			//注：此处可再继续扩展页眉和页脚的处理
			
			//将处理好的Word写到文件中
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			doc.write(baos);
			byte [] dataBytes = baos.toByteArray();
			FileOutputStream fos = new FileOutputStream(path+"test_out2.docx");
    	    fos.write(dataBytes);
    	    fos.close();
    	    System.out.println("处理完成");
    	    
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main3(String[] args) {
		try {
			String path = "E:\\logs\\GUIXWSIGN.docx";
			OPCPackage pack = POIXMLDocument.openPackage(path);
			CustomXWPFDocument document = new CustomXWPFDocument(pack);
			String picId = document.addPictureData(new FileInputStream("E:\\logs\\GUIXW.png"), XWPFDocument.PICTURE_TYPE_PNG);
			document.createPicture(picId, document.getNextPicNameNumber(XWPFDocument.PICTURE_TYPE_PNG), 200, 150);
			FileOutputStream fos = new FileOutputStream(new File("E:\\logs\\updatedTemplate.docx"));
			document.write(fos);
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	/**
	public static void main(String[] args) {
		try {
			String path = "E:\\logs\\GUIXWSIGN.docx";
			File targetFile = new File(path);
			FileInputStream in = new FileInputStream(targetFile);
			//CustomXWPFDocument document = new CustomXWPFDocument(in);
			CustomXWPFDocument document = new CustomXWPFDocument();
			String picId = document.addPictureData(new FileInputStream("E:\\logs\\GUIXW.png"),XWPFDocument.PICTURE_TYPE_JPEG);
			document.createPicture(picId, document.getNextPicNameNumber(XWPFDocument.PICTURE_TYPE_JPEG), 200, 150);
			FileOutputStream fos = new FileOutputStream(new File("E:\\logs\\updatedTemplate.docx"));
		    document.write(fos);
		    fos.close(); 
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	public static void main(String[] args) {
		try {
			InputStream is = new FileInputStream(new File("E:\\logs\\GUIXWSIGN.doc"));  
    		WordExtractor ex = new WordExtractor(is);  
    		String text2003 = ex.getText();  
    		System.out.println(text2003);  
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	public static void main(String[] args) {
		File file = null;
		WordExtractor extractor = null ;
		try {

			file = new File("E:\\logs\\GUIXWSIGN.doc");
			FileInputStream fis=new FileInputStream(file.getAbsolutePath());
			HWPFDocument document=new HWPFDocument(fis);
			extractor = new WordExtractor(document);
			String [] fileData = extractor.getParagraphText();
			for(int i=0;i<fileData.length;i++){
				if(fileData[i] != null)
					System.out.println(fileData[i]);
			}
		}
		catch(Exception exep){}
	}
	**/
	public static void main(String[] args) throws Exception{
		FileInputStream file;
		try {
			file=new FileInputStream("E:\\logs\\GUIXWSIGN.doc");
			byte[] contentBytes = null;
			ByteArrayInputStream  hinput=new ByteArrayInputStream(contentBytes);
			HWPFDocument hDocument= new HWPFDocument(hinput); 
			Range rang= hDocument.getRange();
			String string=rang.text();
			//rang.replaceText("SIGNNUM", "WZ-2014-10-001");
			System.out.println(string);
			OutputStream fos = new FileOutputStream("E:\\logs\\GUIXWSIGN1.doc");
			hDocument.write(fos);
			fos.close();
		} catch (Exception e)
		{    // TODO Auto-generated catch block    e.printStackTrace();}
		}
	}
	/**
     * 用值替换模板中有固定标志的值
     * @param contentBytes :二进制文档模板文件
     * @param value：替换模板中固定标志的值
     * @return
     */
    public byte[] replaceModuleByValue(String DocModule, Map dataMap) {
    	try { 
    		
    		//规定报表模板必须放在maximo 的resources\defaults
    		//System.out.println("处理完成  com/config/report.cfg");
    		String sReportpath = loadConfigValue("com/config/report.cfg","reportpath");
    		String path   = sReportpath+ System.getProperties().getProperty("file.separator")+DocModule;
    		//System.out.println("path = "+path);
			OPCPackage pack = POIXMLDocument.openPackage(path);
			CustomXWPFDocument doc = new CustomXWPFDocument(pack);
    		PoiUtil.processTable(doc, dataMap);
			//PoiUtil.addImage(doc, dataMap);
			PoiUtil.replaceText(doc, dataMap);
			//注：此处可再继续扩展页眉和页脚的处理
			//将处理好的Word写到文件中
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			doc.write(baos);
			return baos.toByteArray();
    	} catch (Exception e) {
    		// TODO Auto-generated catch block   
    		e.printStackTrace();
    		return null;
    	} 
    }
    
    /**
     * 用值替换模板中有固定标志的值
     * @param contentBytes :二进制文档模板文件
     * @param value：替换模板中固定标志的值
     * not use
     * @return
     */
    public byte[] replaceModuleByValue(byte [] contentBytes, Map dataMap) {
    	try {
    		System.out.println("replaceModuleByValue = 1");
    		//ByteArrayInputStream  hinput=new ByteArrayInputStream(contentBytes);
    		InputStream in = byteTOInputStream(contentBytes);
    		System.out.println("replaceModuleByValue = 2");
			HWPFDocument doc= new HWPFDocument(in);
			System.out.println("replaceModuleByValue = 3");
			Range rang = doc.getRange();
			Set set = dataMap.keySet();
			String newstr = "";
			String oldstr = "";
			for (Object mkey : set) {
				oldstr = (String)mkey;
				newstr = (String)dataMap.get(mkey);
				System.out.println("newstr ="+newstr + ",oldstr="+oldstr);
				System.out.println("rang = "+rang.text());
				rang.replaceText(oldstr,newstr);
				//System.out.println("rang = "+rang.text());
				System.out.println("newstr 1 ="+newstr + ",oldstr 1="+oldstr);
			}
			System.out.println("replaceModuleByValue = 4");
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			System.out.println("replaceModuleByValue = 5");
			doc.write(baos);
			System.out.println("replaceModuleByValue = 6");
			return baos.toByteArray();
    	} catch (Exception e) {
    		// TODO Auto-generated catch block   
    		e.printStackTrace();
    		return null;
    	} 
    }
    // 将byte数组转换成InputStream
 	public static InputStream byteTOInputStream(byte[] in) throws Exception {
 		ByteArrayInputStream is = new ByteArrayInputStream(in);
 		return is;
 	}
    /**
    public byte[] replaceModuleByValue(byte [] contentBytes, Map dataMap) {
    	try { 
    		String sReportpath = loadConfigValue("com/config/report.cfg","reportpath");
    		String path = sReportpath+ System.getProperties().getProperty("file.separator")+"1171.doc";
    		//System.out.println("path new = "+path);
    		File file = new File(path);
    		FileOutputStream fis = null;
    		BufferedOutputStream bos = null;
    		try {
    			fis = new FileOutputStream(file);
    			bos = new BufferedOutputStream(fis);
    			bos.write(contentBytes);
    		} catch (Exception e) {
    			throw new Exception(e);
    		} finally {
    			if (bos != null) {
    				bos.close();
    			}
    			if (fis != null) {
    				fis.close();
    			}
    		}
    		OPCPackage pack = POIXMLDocument.openPackage(path);
			CustomXWPFDocument doc = new CustomXWPFDocument(pack);
    		//PoiUtil.processTable(doc, dataMap);
			//PoiUtil.addImage(doc, dataMap);
			PoiUtil.replaceText(doc, dataMap);
			//注：此处可再继续扩展页眉和页脚的处理
			//将处理好的Word写到文件中
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			doc.write(baos);
			return baos.toByteArray();
    	} catch (Exception e) {
    		// TODO Auto-generated catch block   
    		e.printStackTrace();
    		return null;
    	} 
    }
    **/
    /**
     * 用值替换模板中有固定标志的值
     * @param contentBytes :二进制文档模板文件
     * @param value：替换模板中固定标志的值
     * @return
     */
    public byte[] replaceTableModuleByValue(String DocModule, Map textMap, Map tableMap) {
    	try { 
    		//规定报表模板必须放在maximo 的resources\defaults
    		//System.out.println("处理完成  com/config/report.cfg");
    		String sReportpath = loadConfigValue("com/config/report.cfg","reportpath");
    		String path   = sReportpath+ System.getProperties().getProperty("file.separator")+DocModule;
    		//System.out.println("path = "+path);
			OPCPackage pack = POIXMLDocument.openPackage(path);
			CustomXWPFDocument doc = new CustomXWPFDocument(pack);
			/**此处替换word 文件中文本片段（非表格）*/
			PoiUtil.replaceText(doc, textMap);
			/**此处替换word 文件中表格单元格中文本(完全相同)*/
			PoiUtil.processTable(doc, textMap);
			/**此处替换word 文件中表格单元格中文本片段*/
    		PoiUtil.replaceTableText(doc,tableMap);
			//PoiUtil.addImage(doc, dataMap);
    		
			//注：此处可再继续扩展页眉和页脚的处理
			//将处理好的Word写到文件中
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			doc.write(baos);
			return baos.toByteArray();
    	} catch (Exception e) {
    		// TODO Auto-generated catch block   
    		e.printStackTrace();
    		return null;
    	} 
    }
    
    //读出配置文件
    public String loadConfigValue(String name,String key)
    throws Exception
    {
    	String rc = null;

    	// Get our class loader
    	ClassLoader cl = getClass().getClassLoader();

    	// Attempt to open an input stream to the configuration file.
    	// The configuration file is considered to be a system
    	// resource.
    	java.io.InputStream in;

    	if (cl != null) {
    		in = cl.getResourceAsStream(name);
    	}
    	else {
    		in = ClassLoader.getSystemResourceAsStream(name);
    	}

    	// If the input stream is null, then the configuration file
    	// was not found
    	if (in == null) {
    		throw new Exception("configuration file '" +
    				name + "' not found");
    	}
    	else {
    		try {
    			java.util.Properties m_ConfigProperties = new java.util.Properties();

    			// Load the configuration file into the properties table
    			m_ConfigProperties.load(in);

    			// Got the properties. Pull out the properties that we
    			// are interested in
    			rc  = consume(m_ConfigProperties,key);

    		}
    		finally {
    			// Always close the input stream
    			if (in != null) {
    				try {
    					in.close();
    				}
    				catch (Exception ex) {
    				}
    			}
    		}
    	}
    	return rc;
    }
    /**
     * <p>Consumes the given property and returns the value.
     *
     * @param properties Properties table
     * @param key Key of the property to retrieve and remove from
     * the properties table
     * @return Value of the property, or null if not found
     */
    private String consume(java.util.Properties p, String key)
    {
    	String s = null;

    	if ((p != null) &&
    			(key != null)) {

    		// Get the value of the key
    		s = p.getProperty(key);

    		// If found, remove it from the properties table
    		if (s != null) {
    			p.remove(key);
    		}
    	}
    	return s;
    }
}