poi 导出word,导出表格(复杂表格合并行列)解决方法

如下图:一个table表格,需要作为表格插入到word中;

1、首先对表格做拆分处理

代码如下:

	private String simplifyTable(String tableContent) {
			if(StringUtils.isEmpty(tableContent)) return null;
			Document tableDoc = Jsoup.parse(tableContent);
			Elements trElements = tableDoc.getElementsByTag("tr");
			if(trElements !=null){
				Iterator<Element> eleIterator = trElements.iterator();
				Integer rowNum = 0;
				// 针对于colspan操作
				while(eleIterator.hasNext()){
					rowNum ++;
					Element trElement = eleIterator.next();
					//去除所有样式
					trElement.removeAttr("class");
					Elements tdElements = trElement.getElementsByTag("td");
					List<Element> tdEleList = covertElements2List(tdElements);
					for(int i=0;i<tdEleList.size();i++){
						Element curTdElement = tdEleList.get(i);
						//去除所有样式
						curTdElement.removeAttr("class");
						Element ele = curTdElement.clone();
						String colspanValStr = curTdElement.attr("colspan");
						if(!StringUtils.isEmpty(colspanValStr)){
							ele.removeAttr("colspan");
							Integer colspanVal = Integer.parseInt(colspanValStr);
							for(int k=0;k<colspanVal-1;k++){
								curTdElement.after(ele.outerHtml());
							}
						}
					}
				}
				// 针对于rowspan操作
				List<Element> trEleList = covertElements2List(trElements);
				Element firstTrEle = trElements.first();
				Elements tdElements = firstTrEle.getElementsByTag("td");
				Integer tdCount = tdElements.size();
				for(int i=0;i<tdElements.size();i++){ //获取该列下所有单元格
					for(Element trElement:trEleList){
						List<Element> tdElementList = covertElements2List(trElement.getElementsByTag("td"));
						try{
							tdElementList.get(i);
						}catch(Exception e){
							continue;
						}
						Node curTdNode = tdElementList.get(i);
						Node cNode = curTdNode.clone();
						String rowspanValStr = curTdNode.attr("rowspan");
						if(!StringUtils.isEmpty(rowspanValStr)){
							cNode.removeAttr("rowspan");
							Element nextTrElement = trElement.nextElementSibling();
							Integer rowspanVal = Integer.parseInt(rowspanValStr);
							for(int j=0;j<rowspanVal-1;j++){
								Node tempNode = cNode.clone();
								List<Node> nodeList = new ArrayList<Node>();
								nodeList.add(tempNode);
								if(j > 0)
									nextTrElement = nextTrElement.nextElementSibling();

								Integer indexNum = i+1;
								if(i == 0) indexNum = 0;
								if(indexNum == tdCount) nextTrElement.appendChild(tempNode);
								else nextTrElement.insertChildren(indexNum,nodeList);
							}
						}
					}
				}
			}
			Element tableEle = tableDoc.getElementsByTag("table").first();
			String tableHtml = tableEle.outerHtml();

			return tableHtml;
	}

	private static List<Element> covertElements2List(Elements curElements){
		List<Element> elementList = new ArrayList<Element>();
		Iterator<Element> eleIterator = curElements.iterator();
		while(eleIterator.hasNext()){
			Element curlement = eleIterator.next();
			elementList.add(curlement);
		}
		return elementList;
	}

处理后的表格会稍有变形,如下图:

2、将处理后的表格写入word

String tableHtmlStr = ele.outerHtml();
System.out.println(tableHtmlStr);
String simpleTableHtml = simplifyTable(tableHtmlStr);
System.out.println(simpleTableHtml);
Document tableDoc = Jsoup.parse(simpleTableHtml);
Elements trList = tableDoc.getElementsByTag("tr");
Elements tdList = trList.get(0).getElementsByTag("td");
XWPFTable xwpfTable = document.createTable(trList.size(),tdList.size());
Map<String,Boolean>[][] array = new Map[trList.size()][tdList.size()];
for (int row = 0; row < trList.size(); row++) {
	Element trElement = trList.get(row);
	Elements tds = trElement.getElementsByTag("td");
	for(int col = 0; col < tds.size(); col++) {
		Element colElement = tds.get(col);
		String colspan = colElement.attr("colspan");
		String rowspan = colElement.attr("rowspan");
		String style = colElement.attr("style");
		StringBuilder styleSB = new StringBuilder();
		if(!StringUtils.isEmpty(colspan)){
			int colCount = Integer.parseInt(colspan);
			for(int i=0;i<colCount-1;i++){
				array[row][col+i+1] = new HashMap<String, Boolean>();
				array[row][col+i+1].put("mergeCol", true);
			}
		}
		if(!StringUtils.isEmpty(rowspan)){
			int rowCount = Integer.parseInt(rowspan);
			for(int i=0;i<rowCount-1;i++){
				array[row+i+1][col] = new HashMap<String, Boolean>();
				array[row+i+1][col].put("mergeRow", true);
			}
		}
		XWPFTableCell tableCell = xwpfTable.getRow(row).getCell(col);
		if(StringUtils.isEmpty(colspan)){
			if(col == 0){
				if(tableCell.getCTTc().getTcPr() == null){
					tableCell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
				}else{
					if(tableCell.getCTTc().getTcPr().getHMerge() == null){
						tableCell.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.RESTART);
					}else{
						tableCell.getCTTc().getTcPr().getHMerge().setVal(STMerge.RESTART);
					}
				}
			}else{
				if(array[row][col]!=null && array[row][col].get("mergeCol")!=null && array[row][col].get("mergeCol")){
					if(tableCell.getCTTc().getTcPr() == null){
						tableCell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
					}else{
						if(tableCell.getCTTc().getTcPr().getHMerge() == null){
							tableCell.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
						}else{
							tableCell.getCTTc().getTcPr().getHMerge().setVal(STMerge.CONTINUE);
						}
					}
					continue;
				}else{
					if(tableCell.getCTTc().getTcPr() == null){
						tableCell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
					}else{
						if(tableCell.getCTTc().getTcPr().getHMerge() == null){
							tableCell.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.RESTART);
						}else{
							tableCell.getCTTc().getTcPr().getHMerge().setVal(STMerge.RESTART);
						}
					}
				}
			}
		}else{
			if(tableCell.getCTTc().getTcPr() == null){
				tableCell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
			}else{
				if(tableCell.getCTTc().getTcPr().getHMerge() == null){
					tableCell.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.RESTART);
				}else{
					tableCell.getCTTc().getTcPr().getHMerge().setVal(STMerge.RESTART);
				}
			}
		}
		if(StringUtils.isEmpty(rowspan)){
			if(array[row][col]!=null && array[row][col].get("mergeRow")!=null && array[row][col].get("mergeRow")){
				if(tableCell.getCTTc().getTcPr() == null){
					tableCell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
				}else{
					if(tableCell.getCTTc().getTcPr().getVMerge() == null){
						tableCell.getCTTc().getTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
					}else{
						tableCell.getCTTc().getTcPr().getVMerge().setVal(STMerge.CONTINUE);
					}
				}
				continue;
			}else{
				if(tableCell.getCTTc().getTcPr() == null){
					tableCell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
				}else{
					if(tableCell.getCTTc().getTcPr().getVMerge() == null){
						tableCell.getCTTc().getTcPr().addNewVMerge().setVal(STMerge.RESTART);
					}else{
						tableCell.getCTTc().getTcPr().getVMerge().setVal(STMerge.RESTART);
					}
				}
			}
		}else{
			if(tableCell.getCTTc().getTcPr() == null){
				tableCell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
			}else{
				if(tableCell.getCTTc().getTcPr().getVMerge() == null){
					tableCell.getCTTc().getTcPr().addNewVMerge().setVal(STMerge.RESTART);
				}else{
					tableCell.getCTTc().getTcPr().getVMerge().setVal(STMerge.RESTART);
				}
			}
		}
		tableCell.removeParagraph(0);
		XWPFParagraph paragraph = tableCell.addParagraph();
		paragraph.setStyle(styleSB.toString());
		if(!StringUtils.isEmpty(style) && style.contains("text-align:center")){
			paragraph.setAlignment(ParagraphAlignment.CENTER);
		}
		XWPFRun run = paragraph.createRun();
		run.setText(colElement.text());
	}
}

写入word后表格如下图:

注:上述内容处理的表格为html代码的table表格

时间: 2024-11-06 03:51:10

poi 导出word,导出表格(复杂表格合并行列)解决方法的相关文章

表格线边框重复css解决方法

1.td 的边框和table 的边框重叠 .table { border-left:1px solid #dedede; border-top:1px solid #dedede;} .td { border-right:1px solid #dedede; border-bottom:1px solid #dedede;} table 只用左边框和上边框,每个td只有右边框和下边框,效果就是整个表格左.上边框是连续实线,右.下边框是延续td的边框所以是断断续续的 解决方法: .table {b

【POI】对于POI无法处理超大xls等文件,官方解决方法【未研究,待定】

本次使用POI处理xlsx文件,莫名的遇到了一个无法逾越的问题. 总共71个xlsx文件,单个文件最大达到50M以上,71个xls文件摆在那里就有3-4G的大小. 在起始处理的时候,发现原本适用于正常大小的POI处理xls程序竟然屡次的报错GC outofmemory 的内存移除的问题. [当前状况] ①一个50M大小的xlsx文件,使用压缩文件打开,可以看到xml文件达到900M以上 ②一个50M大小以上的xlsx文件,单个工作簿,行数平均在15W行---40W之间,列数在64列左右 ③单方面

Word撤销键(Ctrl+z)无效的解决方法

最近翻译一本新书,Word2013用的较多,于是发现了一个奇怪的问题,撤销按钮一直是灰色.编辑的时候闪一下,又变为灰色.按Ctrl-Z也同样不管用.中文资源里面的解决方法都是用winword.exe /safe启动一次,再进入Word就恢复正常了(例如这篇文章).但是这个方法不是一劳永逸的.我又查了下英文资源,找到一个改注册表的方法. 关闭正在运行的所有程序. 按Win-R,在运行框中键入regedit,然后单击“确定”. 在注册表编辑器中,展开到下列注册表子项: Microsoft Offic

poi 导出word,导出图片解决方法

    /**  * 写入图片  * @param document  * @param picName  * @param width  * @param height  * @param alignment   */ private void WriteImage(CustomXWPFDocument document, String picName, int width, int height, ParagraphAlignment alignment) { try { CustomXWP

phpExcel导出大量数据出现内存溢出错误的解决方法

phpExcel将读取的单元格信息保存在内存中,我们可以通过 代码如下:PHPExcel_Settings::setCacheStorageMethod() 来设置不同的缓存方式,已达到降低内存消耗的目的! 1.将单元格数据序列化后保存在内存中 代码如下: PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized; 2.将单元格序列化后再进行Gzip压缩,然后保存在内存中 代码如下: PHPExcel_CachedObject

Office word 2007不能另存为pdf格式的解决方法

我们在使用Office word 2007时,经常会使用到另存为 PDF 或 XPS(P),遗憾的是,很多人都找不到这个选项, 或者在安装word的时候,并没有安装该加载项,需要你在后期安装,我们来怎么解决没有“另存为PDF或XPS”选项怎么办. 1.打开office word 2007,按快捷键F1打开帮助,在搜索框中输入pdf.点击启用对其他文件格式(如 PDF 和 XPS)的支持 2.在出现的页面中,翻到如下界面,点击连接,按相应的语言,下载 2007 Microsoft Office 加

jquery插入复杂表格,合并行列

原文:jquery插入复杂表格,合并行列 此方法为个人测试所写,针对各种兼容性问题还未测试,初写的目的是easyui复杂表头有些缺陷,比如某个表头合并两列, 在easyui中这样操作无法绑定两个值 或者说我没找到 再或者 可以做个隐藏 数据列 ,不过闲来无事 自己写了写jquery,下面进入正题 先展示下效果 指标性选择为 表头的隐藏用 (客户要求可自定义表头,在extjs中表单自带这个功能,不过复杂表头好像也不支持,单行表头判断条件少的多,比较好实现) 从图片中 可以看到 复杂表头,数据自动合

ueditor表格边框没有颜色的解决

问题: 用ueditor画表格,会发现表格存在,但是表格边框没有颜色. 解决方法: 需要对js文件中的样式进行修改,这里我引用的编辑器样式文件是ueditor.all.min.js,所以先找到该文件,有三个部分需要修改.注意:不同版本的js代码可能会有细微不同. 1.搜索到下面部分: c.push('<td width="'+b+'" vAlign="'+a.tdvalign+'" >'+(r.ie?e.fillChar:"<br/>

Egit的merge合并冲突具体解决方法

稍微总结下弄了半个下午的egit的merge合并冲突解决方法,网上看的都是一个模板出来的,看的糊里糊涂,花了很多时间去实验整个合并流程.. 前提工作 创建一个普通JAVA工程Test,创建一个类Test,写点东西并加入到本地git库: 创建个develop分支,创建个Develop类,修改Test类的某些语句,添加新代码段,提交: 切换到master分支,创建个Master类,修改Test类的同一部分语句,提交: 以上三条操作不进行详细说明,很简单的. 合并过程 打开git repository