精华内容
下载资源
问答
  • 一、POI写入word文档 首先参考W3Shool的教程(上述快速指南)的“Apache POI Word - 文档”一节,对于创建文档和写入段落都有清晰的阐释。我不再赘述。但是其写入段落的方式每次都会覆盖曾经写入的内容。那么经过我...

    引文:Apache POI Word - 快速指南

    一、POI写入word文档

    首先参考W3Shool的教程(上述快速指南)的“Apache POI Word - 文档”一节,对于创建文档和写入段落都有清晰的阐释。我不再赘述。但是其写入段落的方式每次都会覆盖曾经写入的内容。那么经过我探索一番要这么处理...

    二、POI追加写入word文档

    W3SHOOL教程段落覆盖是因为每次都会重建已经存在的文件

    FileOutputStream out = new FileOutputStream(
       new File("createparagraph.docx"));

    所以你需要做的就是保存文件的引用,多次使用即可,注意事项也已经注释好,大家自行阅读。

    public class WebPageHelper {
    
        private static XWPFDocument document;
        private static FileOutputStream out;
        private static String OUTPATH = "X:/XXXX/XXXXX/XXXX";
    
        public static File createDoc(String filePath) throws IOException {
            File file = new File(filePath);
            document = new XWPFDocument();    /*document对象可以只创建一次*/
            System.out.println("created successfully");
            return file;                      /*同一个file的引用,要多次使用才不会被覆盖*/
        }
    
        public static void writePara(String paraStr, File file) throws IOException {
            /*对于每个new的OutputStream对象,只能被document.write()执行一次保存操作*/
            /*所以每次写入新的段落都要新建OutputStream,否则执行第二次会报错*/
            out = new FileOutputStream(file);    
    
            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun run = paragraph.createRun();
            run.setText(paraStr);       /*run.setText()是默认追加写入数据的,不用设置什么*/
    
            document.write(out);        /*保存修改*/
            out.close();                /*记得关闭资源*/
    
            System.out.println("write successful");
        }
    }

    三、报错解决

    对于每个new的OutputStream对象,只能被document.write()执行一次保存操作,所以每次写入新的段落都要新建OutputStream,否则执行第二次会报错,代码见文中。

    四、存在问题

    1. 这个方式每执行一次document.write()就相当于按了一次ctrl+s,调用一次函数就要保存一次,不仅效率低,并且在保存过程未结束时终止程序还会导致文件出错无法打开。所以我再看看有没有其它办法,后续补充。

    2. 虽然上文说run.setText()是默认追加写入数据,但是要保存一次,才能setText()一次,否则在保存前的新写入都是对于新变化的覆盖操作。

    解决方法讨论:我认为可以先用StringBuilder缓存要大量不断添加的字串,定期保存一次,就可以解决以上两个问题啦。欢迎有其他思路的朋友在下方留言。

    五、依赖包下载

    在maven repository搜索POI,找一个使用人数多的版本下载即可,也可以自行配置gradle。

    六、扩展

    [简单]poi操作word 2007 常用方法总结

    Apache POI使用详解

    这两篇文章对于段间距、时间、标签、页眉页脚都有描述,非常全面可以参考。

    展开全文
  • POI写入word

    2019-06-25 14:18:23
    * Word中的大纲级别,可以通过getPPr().getOutlineLvl()直接提取,但需要注意,Word中段落级别,通过如下三种方式定义: * 1、直接对段落进行定义; 2、对段落的样式进行定义; 3、对段落样式的基础样式进行定义...
    package com.test;
    
    import java.io.ByteArrayInputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.math.BigInteger;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
    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.XWPFStyle;
    import org.apache.poi.xwpf.usermodel.XWPFStyles;
    import org.apache.poi.xwpf.usermodel.XWPFTable;
    import org.apache.poi.xwpf.usermodel.XWPFTableCell;
    import org.apache.poi.xwpf.usermodel.XWPFTableRow;
    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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STStyleType;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
    
    public class ReadDoc {
    	private static Map<String, Map<String, Object>> orderMap = new HashMap<String, Map<String, Object>>();
    
    	public void init(String targetPath, String sourcePath) {
    		InputStream is = null;
    		XWPFDocument doc = null;
    		OutputStream out = null;
    		try {
    			XWPFDocument createDoc = new XWPFDocument();
    
    			is = new FileInputStream(sourcePath);
    			doc = new XWPFDocument(is);
    			// 获取段落
    			List<XWPFParagraph> paras = doc.getParagraphs();
    
    			for (XWPFParagraph para : paras) {
    				// System.out.println(para.getCTP());//得到xml格式
    				System.out.println(para.getStyleID());// 段落级别
    				System.out.println(para.getParagraphText());// 段落内容
    
    				String titleLvl = getTitleLvl(doc, para);// 获取段落级别
    				if ("a5".equals(titleLvl) || "HTML".equals(titleLvl) || "".equals(titleLvl) || null == titleLvl) {
    					titleLvl = "8";
    				}
    				System.out.println(titleLvl + "-----");// 0,1,2
    				if (!"8".equals(titleLvl)) {
    					System.out.println(titleLvl + "====" + para.getParagraphText());
    				}
    
    				XWPFParagraph ctPara = createDoc.createParagraph();
    				// 一个XWPFRun代表具有相同属性的一个区域。
    				XWPFRun ctRun = ctPara.createRun();
    				String ctText = para.getParagraphText();
    				ctRun.setFontFamily("宋体");// 字体
    				ctRun.setFontSize(12);
    
    				if (null != titleLvl && !"".equals(titleLvl) && !"8".equals(titleLvl)) {
    					addCustomHeadingStyle(createDoc, titleLvl, Integer.parseInt(titleLvl));
    					String orderCode = getOrderCode(titleLvl);// 获取编号
    					ctText = orderCode + " " + ctText;
    					ctRun.setBold(true);// 标题加粗
    					ctRun.setFontSize(14);
    
    					ctPara.setStyle(titleLvl);
    
    				} else {// 正文
    					ctPara.setIndentationFirstLine(567);// 首行缩进:567==1厘米
    //                  ctRun.setTextPosition(6);//设置行间距
    				}
    
    				ctRun.setText(ctText);// 内容
    			}
    			out = new FileOutputStream(targetPath);
    			createDoc.write(out);
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				if (null != out) {
    					out.close();
    				}
    				if (null != is) {
    					is.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    	/**
    	 * Word中的大纲级别,可以通过getPPr().getOutlineLvl()直接提取,但需要注意,Word中段落级别,通过如下三种方式定义:
    	 * 1、直接对段落进行定义; 2、对段落的样式进行定义; 3、对段落样式的基础样式进行定义。
    	 * 因此,在通过“getPPr().getOutlineLvl()”提取时,需要依次在如上三处读取。
    	 * 
    	 * @param doc
    	 * @param para
    	 * @return
    	 */
    	private static String getTitleLvl(XWPFDocument doc, XWPFParagraph para) {
    		String titleLvl = "";
    		try {
    			// 判断该段落是否设置了大纲级别
    			if (para.getCTP().getPPr().getOutlineLvl() != null) {
    				// System.out.println("getCTP()");
    //              System.out.println(para.getParagraphText());
    //              System.out.println(para.getCTP().getPPr().getOutlineLvl().getVal());
    
    				return String.valueOf(para.getCTP().getPPr().getOutlineLvl().getVal());
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		try {
    			// 判断该段落的样式是否设置了大纲级别
    			if (doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl() != null) {
    
    				// System.out.println("getStyle");
    //              System.out.println(para.getParagraphText());
    //              System.out.println(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl().getVal());
    
    				return String.valueOf(
    						doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl().getVal());
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		try {
    			// 判断该段落的样式的基础样式是否设置了大纲级别
    			if (doc.getStyles().getStyle(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal())
    					.getCTStyle().getPPr().getOutlineLvl() != null) {
    				// System.out.println("getBasedOn");
    //              System.out.println(para.getParagraphText());
    				String styleName = doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal();
    //              System.out.println(doc.getStyles().getStyle(styleName).getCTStyle().getPPr().getOutlineLvl().getVal());
    
    				return String
    						.valueOf(doc.getStyles().getStyle(styleName).getCTStyle().getPPr().getOutlineLvl().getVal());
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		try {
    			if (para.getStyleID() != null) {
    				return para.getStyleID();
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		return titleLvl;
    	}
    
    	/**
    	 * 增加自定义标题样式。这里用的是stackoverflow的源码
    	 * 
    	 * @param docxDocument 目标文档
    	 * @param strStyleId   样式名称
    	 * @param headingLevel 样式级别
    	 */
    	private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {
    
    		CTStyle ctStyle = CTStyle.Factory.newInstance();
    		ctStyle.setStyleId(strStyleId);
    
    		CTString styleName = CTString.Factory.newInstance();
    		styleName.setVal(strStyleId);
    		ctStyle.setName(styleName);
    
    		CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
    		indentNumber.setVal(BigInteger.valueOf(headingLevel));
    
    		// lower number > style is more prominent in the formats bar
    		ctStyle.setUiPriority(indentNumber);
    
    		CTOnOff onoffnull = CTOnOff.Factory.newInstance();
    		ctStyle.setUnhideWhenUsed(onoffnull);
    
    		// style shows up in the formats bar
    		ctStyle.setQFormat(onoffnull);
    
    		// style defines a heading of the given level
    		CTPPr ppr = CTPPr.Factory.newInstance();
    		ppr.setOutlineLvl(indentNumber);
    		ctStyle.setPPr(ppr);
    
    		XWPFStyle style = new XWPFStyle(ctStyle);
    
    		// is a null op if already defined
    		XWPFStyles styles = docxDocument.createStyles();
    
    		style.setType(STStyleType.PARAGRAPH);
    		styles.addStyle(style);
    		
    	}
    	
    	/**
    	 * @param id
    	 * @param width
    	 *            宽
    	 * @param height
    	 *            高
    	 * @param paragraph
    	 *            段落
    	 */
    	public static void createPicture(XWPFDocument docxDocument, int id, int width, int height, XWPFParagraph paragraph) {
    		final int EMU = 9525;
    		width *= EMU;
    		height *= EMU;
    		String blipId = docxDocument.getAllPictures().get(id).getPackageRelationship().getId();
    		CTInline inline = paragraph.createRun().getCTR().addNewDrawing().addNewInline();
    		String picXml = ""
    				+ "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
    				+ "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
    				+ "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
    				+ "         <pic:nvPicPr>" + "            <pic:cNvPr id=\""
    				+ id
    				+ "\" name=\"Generated\"/>"
    				+ "            <pic:cNvPicPr/>"
    				+ "         </pic:nvPicPr>"
    				+ "         <pic:blipFill>"
    				+ "            <a:blip r:embed=\""
    				+ blipId
    				+ "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
    				+ "            <a:stretch>"
    				+ "               <a:fillRect/>"
    				+ "            </a:stretch>"
    				+ "         </pic:blipFill>"
    				+ "         <pic:spPr>"
    				+ "            <a:xfrm>"
    				+ "               <a:off x=\"0\" y=\"0\"/>"
    				+ "               <a:ext cx=\""
    				+ width
    				+ "\" cy=\""
    				+ height
    				+ "\"/>"
    				+ "            </a:xfrm>"
    				+ "            <a:prstGeom prst=\"rect\">"
    				+ "               <a:avLst/>"
    				+ "            </a:prstGeom>"
    				+ "         </pic:spPr>"
    				+ "      </pic:pic>"
    				+ "   </a:graphicData>" + "</a:graphic>";
    
    		inline.addNewGraphic().addNewGraphicData();
    		XmlToken xmlToken = null;
    		try {
    			xmlToken = XmlToken.Factory.parse(picXml);
    		} catch (XmlException xe) {
    			xe.printStackTrace();
    		}
    		inline.set(xmlToken);
    
    		inline.setDistT(0);
    		inline.setDistB(0);
    		inline.setDistL(0);
    		inline.setDistR(0);
    
    		CTPositiveSize2D extent = inline.addNewExtent();
    		extent.setCx(width);
    		extent.setCy(height);
    
    		CTNonVisualDrawingProps docPr = inline.addNewDocPr();
    		docPr.setId(id);
    		docPr.setName("图片名称");
    		docPr.setDescr("描述信息");
    	}
    
    	/**
    	 * 获取标题编号
    	 * 
    	 * @param titleLvl
    	 * @return
    	 */
    	private static String getOrderCode(String titleLvl) {
    		String order = "";
    
    		if ("0".equals(titleLvl) || Integer.parseInt(titleLvl) == 8) {// 文档标题||正文
    			return "";
    		} else if (Integer.parseInt(titleLvl) > 0 && Integer.parseInt(titleLvl) < 8) {// 段落标题
    
    			// 设置最高级别标题
    			Map<String, Object> maxTitleMap = orderMap.get("maxTitleLvlMap");
    			if (null == maxTitleMap) {// 没有,表示第一次进来
    				// 最高级别标题赋值
    				maxTitleMap = new HashMap<String, Object>();
    				maxTitleMap.put("lvl", titleLvl);
    				orderMap.put("maxTitleLvlMap", maxTitleMap);
    			} else {
    				String maxTitleLvl = maxTitleMap.get("lvl") + "";// 最上层标题级别(0,1,2,3)
    				if (Integer.parseInt(titleLvl) < Integer.parseInt(maxTitleLvl)) {// 当前标题级别更高
    					maxTitleMap.put("lvl", titleLvl);// 设置最高级别标题
    					orderMap.put("maxTitleLvlMap", maxTitleMap);
    				}
    			}
    
    			// 查父节点标题
    			int parentTitleLvl = Integer.parseInt(titleLvl) - 1;// 父节点标题级别
    			Map<String, Object> cMap = orderMap.get(titleLvl);// 当前节点信息
    			Map<String, Object> pMap = orderMap.get(parentTitleLvl + "");// 父节点信息
    
    			if (0 == parentTitleLvl) {// 父节点为文档标题,表明当前节点为1级标题
    				int count = 0;
    				// 最上层标题,没有父节点信息
    				if (null == cMap) {// 没有当前节点信息
    					cMap = new HashMap<String, Object>();
    				} else {
    					count = Integer.parseInt(String.valueOf(cMap.get("cCount")));// 当前序个数
    				}
    				count++;
    				order = count + "";
    				cMap.put("cOrder", order);// 当前序
    				cMap.put("cCount", count);// 当前序个数
    				orderMap.put(titleLvl, cMap);
    
    			} else {// 父节点为非文档标题
    				int count = 0;
    				// 如果没有相邻的父节点信息,当前标题级别自动升级
    				if (null == pMap) {
    					return getOrderCode(String.valueOf(parentTitleLvl));
    				} else {
    					String pOrder = String.valueOf(pMap.get("cOrder"));// 父节点序
    					if (null == cMap) {// 没有当前节点信息
    						cMap = new HashMap<String, Object>();
    					} else {
    						count = Integer.parseInt(String.valueOf(cMap.get("cCount")));// 当前序个数
    					}
    					count++;
    					order = pOrder + "." + count;// 当前序编号
    					cMap.put("cOrder", order);// 当前序
    					cMap.put("cCount", count);// 当前序个数
    					orderMap.put(titleLvl, cMap);
    				}
    			}
    
    			// 字节点标题计数清零
    			int childTitleLvl = Integer.parseInt(titleLvl) + 1;// 子节点标题级别
    			Map<String, Object> cdMap = orderMap.get(childTitleLvl + "");//
    			if (null != cdMap) {
    				cdMap.put("cCount", 0);// 子节点序个数
    				orderMap.get(childTitleLvl + "").put("cCount", 0);
    			}
    		}
    		return order;
    	}
    
    	public static void main(String[] args) {
    		InputStream is = null;
    		OutputStream out = null;
    		try {
    			XWPFDocument createDoc = new XWPFDocument();
    			
    			addCustomHeadingStyle(createDoc, "z标题 1", 1);
    		    addCustomHeadingStyle(createDoc, "z标题 2", 2); // 标题 1
    		    XWPFParagraph paragraph = createDoc.createParagraph();
    		    XWPFRun run = paragraph.createRun();
    		    run.setText("z标题 1");
    		    run.setFontFamily("宋体");// 字体
    		    run.setBold(true);
    			run.setFontSize(24);
    		    paragraph.setStyle("z标题 1"); // 标题 2
    		    paragraph.setAlignment(ParagraphAlignment.CENTER);//对齐方式
    		    XWPFParagraph paragraph2 = createDoc.createParagraph();
    		    XWPFRun run2 = paragraph2.createRun();
    		    run2.setText("z标题 2");
    		    run2.setFontFamily("宋体");// 字体
    		    run2.setBold(true);
    			run2.setFontSize(20);
    		    paragraph2.setStyle("z标题 2"); // 正文
    		    paragraph2.setAlignment(ParagraphAlignment.CENTER);//对齐方式
    		    XWPFParagraph paragraphX = createDoc.createParagraph();
    		    XWPFRun runX = paragraphX.createRun();
    		    runX.setText("正文"); // word 写入到文件
    			
    
    			/*is = new FileInputStream("D:/20190417-MRO-工程设计-招标书(标段一).docx");
    			doc = new XWPFDocument(is);
    			// 获取段落
    			List<XWPFParagraph> paras = doc.getParagraphs();*/
    
    			// for (XWPFParagraph para : paras) {
    			// System.out.println("得到xml格式-->" + para.getCTP());//得到xml格式
    			// System.out.println("段落级别-->" + para.getStyleID());// 段落级别
    			// System.out.println("段落内容-->" + para.getParagraphText());// 段落内容
    
    			/*
    			 * String titleLvl = getTitleLvl(doc, para);// 获取段落级别 if ("a5".equals(titleLvl)
    			 * || "HTML".equals(titleLvl) || "".equals(titleLvl) || null == titleLvl) {
    			 * titleLvl = "8"; } System.out.println("获取段落级别-->" + titleLvl);// 0,1,2 if
    			 * (!"8".equals(titleLvl)) { System.out.println("获取段落级别-->" + titleLvl +
    			 * "====段落内容-->" + para.getParagraphText()); }
    			 */
    
    			XWPFParagraph ctPara = createDoc.createParagraph();
    			// 一个XWPFRun代表具有相同属性的一个区域。
    			XWPFRun ctRun = ctPara.createRun();
    			ctPara.setIndentationFirstLine(567);// 首行缩进:567==1厘米 //
    			// String ctText = para.getParagraphText();
    			ctRun.setFontFamily("宋体");// 字体
    			ctRun.setFontSize(12);
    			ctRun.setTextPosition(6);//设置行间距
    
    			String con = "areaTxt--><h1 style=\"text-align: center;\"><span style=\"font-weight: bold; font-family: 宋体; background-color: rgb(194, 79, 74);\">15</span></h1><div><span style=\"font-family: 宋体; background-color: rgb(255, 255, 255);\">1sdfsdf</span></div><div><span style=\"font-family: 宋体; background-color: rgb(255, 255, 255);\">2水电费都是发生的</span></div>";
    
    			ctRun.setText(con);// 内容
    			// }
    			XWPFParagraph ctPara2 = createDoc.createParagraph();
    			XWPFRun ctRun2 = ctPara2.createRun();
    			// String ctText = para.getParagraphText();
    			ctRun2.setFontFamily("宋体");// 字体
    			ctRun2.setFontSize(12);
    
    			String con2 = "areaTxt--><h1 style=\"text-align: center;\"><span style=\"font-weight: bold; font-family: 宋体; background-color: rgb(194, 79, 74);\">15</span></h1><div><span style=\"font-family: 宋体; background-color: rgb(255, 255, 255);\">1sdfsdf</span></div><div><span style=\"font-family: 宋体; background-color: rgb(255, 255, 255);\">2水电费都是发生的</span></div>";
    
    			ctRun2.setText(con2);// 内容
    
    			// XWPFDocument doc = new XWPFDocument(); // 创建一个 5 行 5 列的表格
    			XWPFTable table = createDoc.createTable(5, 5); // 这里增加的列原本初始化创建的那 5 行在通过 getTableCells()方法获取时获取不到,但通过 row 新增的就可以。
    			//table.addNewCol(); // 给表格增加一列,变成 6 列
    			table.createRow(); // 给表格新增一行,变成 6 行
    			List<XWPFTableRow> rows = table.getRows(); // 表格属性
    			CTTblPr tablePr = table.getCTTbl().addNewTblPr(); // 表格宽度
    			CTTblWidth width = tablePr.addNewTblW();
    			width.setW(BigInteger.valueOf(8000));
    			XWPFTableRow row;
    			List<XWPFTableCell> cells;
    			XWPFTableCell cell;
    			for (int i1 = 0; i1 < rows.size(); i1++) {
    				row = rows.get(i1); // 新增单元格
    				row.addNewTableCell(); // 设置行的高度
    				row.setHeight(500); // 行属性 //CTTrPr rowPr = row.getCtRow().addNewTrPr(); // 这种方式是可以获取到新增的 cell 的。
    									// //List list = row.getCtRow().getTcList();
    				cells = row.getTableCells();
    				for (int j = 0; j < cells.size(); j++) {
    					cell = cells.get(j);
    					if ((i1 + j) % 2 == 0) { // 设置单元格的颜色
    						cell.setColor("ff0000"); // 红色
    					} else {
    						cell.setColor("0000ff"); // 蓝色
    					} // 单元格属性
    					CTTcPr cellPr = cell.getCTTc().addNewTcPr();
    					cellPr.addNewVAlign().setVal(STVerticalJc.CENTER);
    					if (j == 3) { // 设置宽度
    						cellPr.addNewTcW().setW(BigInteger.valueOf(3000));
    					}
    					cell.setText(i1 + "," + j);
    				}
    			}
    			
    			
    			FileInputStream in = new FileInputStream("IMG20190130_160416.png");
    			byte[] ba = new byte[in.available()];
    			in.read(ba);
    			ByteArrayInputStream byteInputStream = new ByteArrayInputStream(ba);
    			XWPFParagraph picture = createDoc.createParagraph();
    			//添加图片
    			createDoc.addPictureData(byteInputStream, XWPFDocument.PICTURE_TYPE_PNG);
    			//图片大小、位置
    			createPicture(createDoc, createDoc.getAllPictures().size() - 1, 500, 500, picture);
    			
    			
    			// 文件不存在时会自动创建
    			out = new FileOutputStream("new1.docx");
    			createDoc.write(out);
    
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				if (null != out) {
    					out.close();
    				}
    				if (null != is) {
    					is.close();
    				}
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }

     

    展开全文
  • POI生成word文档

    2019-01-18 15:46:16
    最近在做一个出卷系统,需要通过试卷模板从数据库中抽取题目,然后按照模板的样式生成完整的试卷,包括试卷格式的排版和图片的写入。这是用POI模板生成word文档。里面包括完整代码和所需jar包。
  • 第一步,继承XWPFDocument,写一个操作图片写入大小、位置的方法, 如果没有此方法,图片写入不会报错,但是打开Word文档,会看不到图片: package word; import java.io.IOException; import java.io....

    第一步,继承XWPFDocument,写一个操作图片写入大小、位置的方法, 如果没有此方法,图片写入不会报错,但是打开Word文档,会看不到图片:

    package word;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.apache.poi.openxml4j.opc.OPCPackage;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    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;
    
    public class CustomXWPFDocument extends XWPFDocument{
    	public CustomXWPFDocument(InputStream in) throws IOException {
    		super(in);
    	}
    
    	public CustomXWPFDocument() {
    		super();
    	}
    
    	public CustomXWPFDocument(OPCPackage pkg) throws IOException {
    		super(pkg);
    	}
    
    	/**
    	 * @param id
    	 * @param width
    	 *            宽
    	 * @param height
    	 *            高
    	 * @param paragraph
    	 *            段落
    	 */
    	public void createPicture(int id, int width, int height,
    			XWPFParagraph paragraph) {
    		final int EMU = 9525;
    		width *= EMU;
    		height *= EMU;
    		String blipId = getAllPictures().get(id).getPackageRelationship()
    				.getId();
    		CTInline inline = paragraph.createRun().getCTR().addNewDrawing()
    				.addNewInline();
    		String picXml = ""
    				+ "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
    				+ "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
    				+ "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
    				+ "         <pic:nvPicPr>" + "            <pic:cNvPr id=\""
    				+ id
    				+ "\" name=\"Generated\"/>"
    				+ "            <pic:cNvPicPr/>"
    				+ "         </pic:nvPicPr>"
    				+ "         <pic:blipFill>"
    				+ "            <a:blip r:embed=\""
    				+ blipId
    				+ "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
    				+ "            <a:stretch>"
    				+ "               <a:fillRect/>"
    				+ "            </a:stretch>"
    				+ "         </pic:blipFill>"
    				+ "         <pic:spPr>"
    				+ "            <a:xfrm>"
    				+ "               <a:off x=\"0\" y=\"0\"/>"
    				+ "               <a:ext cx=\""
    				+ width
    				+ "\" cy=\""
    				+ height
    				+ "\"/>"
    				+ "            </a:xfrm>"
    				+ "            <a:prstGeom prst=\"rect\">"
    				+ "               <a:avLst/>"
    				+ "            </a:prstGeom>"
    				+ "         </pic:spPr>"
    				+ "      </pic:pic>"
    				+ "   </a:graphicData>" + "</a:graphic>";
    
    		inline.addNewGraphic().addNewGraphicData();
    		XmlToken xmlToken = null;
    		try {
    			xmlToken = XmlToken.Factory.parse(picXml);
    		} catch (XmlException xe) {
    			xe.printStackTrace();
    		}
    		inline.set(xmlToken);
    
    		inline.setDistT(0);
    		inline.setDistB(0);
    		inline.setDistL(0);
    		inline.setDistR(0);
    
    		CTPositiveSize2D extent = inline.addNewExtent();
    		extent.setCx(width);
    		extent.setCy(height);
    
    		CTNonVisualDrawingProps docPr = inline.addNewDocPr();
    		docPr.setId(id);
    		docPr.setName("图片名称");
    		docPr.setDescr("描述信息");
    	}
    }

    第二步,具体操作,写入文字与图片:

    package word;
    
    import java.io.ByteArrayInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    
    public class Test {
    	public static void main(String[] args) throws Exception{
    		exportSimpleWord();
    	}
    
    	public static void exportSimpleWord() throws Exception {
    		CustomXWPFDocument document = new CustomXWPFDocument();
    		String path = "D://测试";
    		FileOutputStream out = new FileOutputStream(new File(path + ".doc"));
    		
    		// 添加标题
    		XWPFParagraph titleParagraph = document.createParagraph();
    		// 设置段落居中
    		titleParagraph.setAlignment(ParagraphAlignment.CENTER);
    		XWPFRun titleRun = titleParagraph.createRun();
    		titleRun.setText("Java操作word文档,插入文字与图片");
    		titleRun.setFontSize(20);
    		titleRun.setFontFamily("宋体");
    		titleRun.setBold(true);
    
    		XWPFParagraph firstParagraph = document.createParagraph();
    		XWPFRun firstRun = firstParagraph.createRun();
    		firstRun.setText("具体操作方式:");
    		firstRun.setFontFamily("仿宋");
    		firstRun.setFontSize(11);
    		//换行
    		firstParagraph.setWordWrap(true);
    		
    		XWPFParagraph twoParagraph = document.createParagraph();
    		twoParagraph.setIndentationFirstLine(500);
    		XWPFRun twoRun = twoParagraph.createRun();
    		twoRun.setFontFamily("仿宋");
    		twoRun.setFontSize(11);
    		twoRun.setText("继承POI操作Word中类XWPFDocument。");
    		
    		FileInputStream in = new FileInputStream("D://logo.jpg");
    		byte[] ba = new byte[in.available()];
    		in.read(ba);
    		ByteArrayInputStream byteInputStream = new ByteArrayInputStream(ba);
    		XWPFParagraph picture = document.createParagraph();
    		//添加图片
    		document.addPictureData(byteInputStream, CustomXWPFDocument.PICTURE_TYPE_JPEG);
    		//图片大小、位置
    		document.createPicture(document.getAllPictures().size() - 1, 100, 100, picture);
    		
    		document.write(out);
    		out.close();
    	}
    }
    

     

    展开全文
  • Java POI 生成Word文档

    万次阅读 多人点赞 2017-01-09 15:31:58
    在开发中有时候我们需要导出MS word文档。最近因为需要做一个生成word文件的功能。就将这块拿出来和大家分享。  生成word文件和我们写word文档是相同的概念,只不过在这里我们换成了用代码来操作。下面的例子中...

    在开发中有时候我们需要导出MS word文档。最近因为需要做一个生成word文件的功能。就将这块拿出来和大家分享。

          生成word文件和我们写word文档是相同的概念,只不过在这里我们换成了用代码来操作。下面的例子中主要有添加页眉,页脚,正文(段落,表格)。在正文中,段落包含文字字体和背景的设置。表格主要是数据的填充和样式(有无边框)。这里写的例子给出的内容只是Java POI 方式生成word文件的极少数的一些方法,需要使用更多方法的还是要自己根据自己的需求去查看API。

           看到很多小伙伴反应不能用的问题,这里我又重新把代码下载下来生成了一次试试。确实是没有问题。以前使用的是jdk6,最后一个版本使用的是jdk8.我再把我的maven导包情况贴出来。供大家参考,生成的文件MS office 和wps打开均没有问题。

    <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>ooxml-schemas</artifactId>
                <version>1.1</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/org.apache.poi.xwpf.converter.core -->
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>org.apache.poi.xwpf.converter.core</artifactId>
                <version>1.0.6</version>
            </dependency>

     

     

    那就直接先上代码吧:

     

    package com.seawater.controller;
    
    import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
    import org.apache.poi.xwpf.usermodel.*;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.math.BigInteger;
    
    
    /**
     * Created by zhouhs on 2017/1/9.
     */
    public class WordExportController {
    
        public static void main(String[] args)throws Exception {
            //Blank Document
            XWPFDocument document= new XWPFDocument();
    
            //Write the Document in file system
            FileOutputStream out = new FileOutputStream(new File("create_table.docx"));
    
    
            //添加标题
            XWPFParagraph titleParagraph = document.createParagraph();
            //设置段落居中
            titleParagraph.setAlignment(ParagraphAlignment.CENTER);
    
            XWPFRun titleParagraphRun = titleParagraph.createRun();
            titleParagraphRun.setText("Java PoI");
            titleParagraphRun.setColor("000000");
            titleParagraphRun.setFontSize(20);
    
    
            //段落
            XWPFParagraph firstParagraph = document.createParagraph();
            XWPFRun run = firstParagraph.createRun();
            run.setText("Java POI 生成word文件。");
            run.setColor("696969");
            run.setFontSize(16);
    
            //设置段落背景颜色
            CTShd cTShd = run.getCTR().addNewRPr().addNewShd();
            cTShd.setVal(STShd.CLEAR);
            cTShd.setFill("97FFFF");
    
    
            //换行
            XWPFParagraph paragraph1 = document.createParagraph();
            XWPFRun paragraphRun1 = paragraph1.createRun();
            paragraphRun1.setText("\r");
    
    
            //基本信息表格
            XWPFTable infoTable = document.createTable();
            //去表格边框
            infoTable.getCTTbl().getTblPr().unsetTblBorders();
    
    
            //列宽自动分割
            CTTblWidth infoTableWidth = infoTable.getCTTbl().addNewTblPr().addNewTblW();
            infoTableWidth.setType(STTblWidth.DXA);
            infoTableWidth.setW(BigInteger.valueOf(9072));
    
    
            //表格第一行
            XWPFTableRow infoTableRowOne = infoTable.getRow(0);
            infoTableRowOne.getCell(0).setText("职位");
            infoTableRowOne.addNewTableCell().setText(": Java 开发工程师");
    
            //表格第二行
            XWPFTableRow infoTableRowTwo = infoTable.createRow();
            infoTableRowTwo.getCell(0).setText("姓名");
            infoTableRowTwo.getCell(1).setText(": seawater");
    
            //表格第三行
            XWPFTableRow infoTableRowThree = infoTable.createRow();
            infoTableRowThree.getCell(0).setText("生日");
            infoTableRowThree.getCell(1).setText(": xxx-xx-xx");
    
            //表格第四行
            XWPFTableRow infoTableRowFour = infoTable.createRow();
            infoTableRowFour.getCell(0).setText("性别");
            infoTableRowFour.getCell(1).setText(": 男");
    
            //表格第五行
            XWPFTableRow infoTableRowFive = infoTable.createRow();
            infoTableRowFive.getCell(0).setText("现居地");
            infoTableRowFive.getCell(1).setText(": xx");
    
    
            //两个表格之间加个换行
            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun paragraphRun = paragraph.createRun();
            paragraphRun.setText("\r");
    
    
    
            //工作经历表格
            XWPFTable ComTable = document.createTable();
    
    
            //列宽自动分割
            CTTblWidth comTableWidth = ComTable.getCTTbl().addNewTblPr().addNewTblW();
            comTableWidth.setType(STTblWidth.DXA);
            comTableWidth.setW(BigInteger.valueOf(9072));
    
            //表格第一行
            XWPFTableRow comTableRowOne = ComTable.getRow(0);
            comTableRowOne.getCell(0).setText("开始时间");
            comTableRowOne.addNewTableCell().setText("结束时间");
            comTableRowOne.addNewTableCell().setText("公司名称");
            comTableRowOne.addNewTableCell().setText("title");
    
            //表格第二行
            XWPFTableRow comTableRowTwo = ComTable.createRow();
            comTableRowTwo.getCell(0).setText("2016-09-06");
            comTableRowTwo.getCell(1).setText("至今");
            comTableRowTwo.getCell(2).setText("seawater");
            comTableRowTwo.getCell(3).setText("Java开发工程师");
    
            //表格第三行
            XWPFTableRow comTableRowThree = ComTable.createRow();
            comTableRowThree.getCell(0).setText("2016-09-06");
            comTableRowThree.getCell(1).setText("至今");
            comTableRowThree.getCell(2).setText("seawater");
            comTableRowThree.getCell(3).setText("Java开发工程师");
    
    
            CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
            XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(document, sectPr);
    
            //添加页眉
            CTP ctpHeader = CTP.Factory.newInstance();
            CTR ctrHeader = ctpHeader.addNewR();
            CTText ctHeader = ctrHeader.addNewT();
            String headerText = "Java POI create MS word file.";
            ctHeader.setStringValue(headerText);
            XWPFParagraph headerParagraph = new XWPFParagraph(ctpHeader, document);
            //设置为右对齐
            headerParagraph.setAlignment(ParagraphAlignment.RIGHT);
            XWPFParagraph[] parsHeader = new XWPFParagraph[1];
            parsHeader[0] = headerParagraph;
            policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT, parsHeader);
    
    
            //添加页脚
            CTP ctpFooter = CTP.Factory.newInstance();
            CTR ctrFooter = ctpFooter.addNewR();
            CTText ctFooter = ctrFooter.addNewT();
            String footerText = "http://blog.csdn.net/zhouseawater";
            ctFooter.setStringValue(footerText);
            XWPFParagraph footerParagraph = new XWPFParagraph(ctpFooter, document);
            headerParagraph.setAlignment(ParagraphAlignment.CENTER);
            XWPFParagraph[] parsFooter = new XWPFParagraph[1];
            parsFooter[0] = footerParagraph;
            policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, parsFooter);
    
    
            document.write(out);
            out.close();
            System.out.println("create_table document written success.");
        }
    
    
    }
    

    代码我放到这一个文件当中了。下面我就一些代码做一些解释,因为有的是我在做的过程中遇到的问题。大部分的代码大家都是一眼就可以看懂的。

     

     

    //设置段落背景颜色
            CTShd cTShd = run.getCTR().addNewRPr().addNewShd();
            cTShd.setVal(STShd.CLEAR);
            cTShd.setFill("97FFFF");

    这段代码设置段落的背景颜色。

     

    如果我们的表格不需要边框呢就加下面的代码:

     

    infoTable.getCTTbl().getTblPr().unsetTblBorders();

    infoTable换成自己的table名称就可以了。
    建立一个表格的时候设置列宽跟随内容伸缩

     

     

    CTTblWidth infoTableWidth = infoTable.getCTTbl().addNewTblPr().addNewTblW();
            infoTableWidth.setType(STTblWidth.DXA);
            infoTableWidth.setW(BigInteger.valueOf(9072));

    其他的代码我就不解释了。运行就可以得到我们的word文件了。

     

    结果:

    1-1
     

    展开全文
  • 使用 Apache Poi 读写 word 文档 写操作: package com.poi.word; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import java.util.List; import org.apache.poi...
  • 最近在做一个自动生成Word文档的东西,需求是基于固定格式的doc文件,对其进行修改后生成一个新的doc文件(修改方法为替换)。 由于poi只提供了简单的读写操作,不支持样式,因此只能先事先准备好带有格式的doc文件...
  • POI操作Word文档工具

    2021-02-20 11:40:10
    POI简介,POI操作文档常用方法、功能以及工具类
  • 我现在做的项目要用到导出文件的功能,然后就去学了Apache POI通过模板文件生成word文档的功能。 我写的demo在main方法和web接口下都能正常生成生成word文档;但是一移植到公司的项目上就报错了,controller和...
  • 在线Api: http://poi.apache.org/apidocs/5.0/ 问题总结 XWPFRun 分段问题 在指定位置填充表格 在表格里面插入表格 插入图片 未解决的问题: 在word里面插入附件 解决问题 XWPFRun 分段问题 例如我要替换word里面...
  • java代码操作POI生成Word文档

    千次阅读 2017-11-07 15:45:57
    突然发现好像跟上传下载以及处理各种文档扛上了,一直在做这方面的东西,今天吧java通过POI生成word文档的代码贴出来,供大家参考。有什么不对之处肯定大家批评指正。import java.io.ByteArrayInputStream; import ...
  • *word设置文档格式 */ XWPFDocument xdoc = new XWPFDocument(); XWPFParagraph p = xdoc.createParagraph(); // 固定值25磅 setParagraphSpacingInfo(p, true, "0", "150", null, null, true, "500", ...
  • poi 读写word文档并下载文件 **本文主要介绍如何将数据导入word文档模板,根据需要动态拼接列,并将模板下载下来 1)首先需要导入依赖包 <dependency> <groupId>org.apache.poi</groupId> &...
  • JAVA POI生成WORD文档

    2021-05-25 17:01:38
    这是我一个csdn文档,这个word生成代码是一年半前写的了,当时也是搞了几天才把这个功能做好,最近刚好想写一下自己觉得值得分享的代码,希望对大家还是有点点帮助 给一张效果图片吧,因为是项目上的数据,我给打了...
  • 在使用POIword doc文件的时候我们必须要先有一个doc文件才行,因为我们在写doc文件的时候是通过HWPFDocument来写的,而HWPFDocument是要依附于一个doc文件的。所以通常的做法是我们先在硬盘上准备好一个内容空白的...
  • POI解析word文档

    万次阅读 2018-07-26 15:50:02
    import ... import org.apache.log4j.Logger; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.model.PicturesTable; import org.apache.poi...
  • java poi 生成word文档并下载

    千次阅读 2020-01-19 11:10:21
    我使用的是Springboot框架开发的。首先需要在pom.xml文件中引入以下maven包: <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> ...
  • POI操作WORD文档,生成的新文档为空白文档 ...... 目前只是找到以上现象,初步结论是表格的规格过大会对生成的WORD文件结果又影响。具体怎么解决还没有找到途径。
  • 1.写入word 1.1 直接通过XWPFDocument生成 在使用XWPFDocument写docx文件时不需要像使用HWPFDocument写doc文件那样必须从一个doc文件开始,我们可以直接new一个空的XWPFDocument,之后再往这个XWPFDocument里面...
  • 模版word文件 生成的word文件 代码 //自己使用做下简单的封装即可 public static void main(String[] args) { //示例数据 Map<String, Object> map = new HashMap<>(); map.put("name", "李四1");...
  • 一、读取word文档写入生成新的word文档: 1.使用工具包:poi-版本号.jar poi-scratchpad-版本号-beta5.jar或poi-scratchpad-版本号.jar 2.代码: import java.io.Byt...
  • java用poi读取word文档的确很容易。不过不同版本之间差别还是挺大的。目前只是试出了poi-3.8-beta4这个版本编辑word内容后输出不是乱码。最新官方版本都是乱码,不知道为什么。贴出代码 FileInputStream ...
  • POI 替换word文档书签

    千次阅读 2019-08-22 12:03:51
    word按照版本为两种:doc和docx,POI针对这两种操作需要不同的API: doc操作使用HWPFDocument,替换思想就是找到书签的起止位置,对范围内的文本进行替换: public static void docOperate(InputStream ...
  • poi解析word文档(解析表格,emf,wmf,svg转jpg图片)

    千次阅读 热门讨论 2017-02-24 11:09:33
    POI解析word文档 poi解析word的表格:  提前先准备需要的jar包:   &lt;!-- poi --&gt; &lt;dependency&gt; &lt;groupId&gt;org.apache.poi&lt;/groupId&gt; &lt...
  • poi操作word文档总结

    万次阅读 2014-06-05 17:18:43
    POI分段落生成纯Word动态模板并导入数据 导出数据,可以用word另存为xml格式的ftl文件,变量用${变量名}表示,然后在类中通过 freemarker去替换变量。...后来找到方法可以分段落读入纯word文档。要找到了word基
  • 近期做动态的word文档生成, 需要在指定XWPFRun生成书签的功能,有两种情况: 创建新word文档时候,直接在createRun前后调用生成书签的方法 XWPFRun oldRun = runs.get(j); CTBookmark ctBookmark = paragraph....
  • POIWord文档读取-yellowcong

    千次阅读 2017-07-16 01:09:53
    POI对于Doc的支持冒失对于新版本的Word不支持,支持的是Word老版本,对于docx结尾的,支持不是特别的好,本文主要分三部分,1、Word的文字不分的读取,2、Wrod图片的读取,3、Word表格读取
  • 将html内容写入word文档

    千次阅读 2017-08-30 17:42:02
    将html内容写入word文档

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,408
精华内容 963
关键字:

poi写入word文档