文章标题
来源:互联网 发布:跳跃网络的游戏有哪些 编辑:程序博客网 时间:2024/06/01 08:15
package com.jeeplus.modules.event.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.poi.POIXMLDocument;
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.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
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.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import com.jeeplus.common.config.CacheLoader;
/**
* 2016-11-8
* @author Administrator
*
*/
public class WordUtil {
public static final String IMAGE_ = "IMAGE_";private static final String EL_LEFT = "<";private static final String EL_RIGHT = ">";private XWPFDocument document = null;private List<String> noSNTable = null;/** * Read and write word by template * @param templatePath The path of the word template * @param outputPath The path of the result word file to write out * @param map The rule that is how to read and write the word for example: * e.g string value replace: The map's key is the text which is ready to * repalce in the word and value of the map is a text insert into word. * e.g image insert: The map's key must start with 'IMAGE_' and value of * the map must be put a path of a image. * e.g list value insert: The map's key is the name of a table in word. * The value of the map must be a instance of calss List and the members * of list is a instance of calss Map and this map as the string value replace map * @return * @throws FileNotFoundException * @throws IOException * @throws InvalidFormatException * 读取文件,返回流,提供下载 */public ByteArrayOutputStream generateWordFromTemplate(String templatePath, String outputPath, Map<String, Object> map, ByteArrayOutputStream ostream) throws FileNotFoundException, IOException, InvalidFormatException { document = new XWPFDocument(POIXMLDocument.openPackage(templatePath)); return readWordDocument(map, outputPath, ostream);}/** * Read and write word by template in inputStream * @param inputStream * @param outputPath * @param map * @return * @throws InvalidFormatException * @throws FileNotFoundException * @throws IOException * 读取 */public ByteArrayOutputStream generateWordFromTemplate(java.io.InputStream inputStream, String outputPath, Map<String, Object> map, ByteArrayOutputStream ostream) throws InvalidFormatException, FileNotFoundException, IOException { document = new XWPFDocument(inputStream); return readWordDocument(map, outputPath, ostream);}/** * 读取文档,并且解析,返回流 * @param map * @param outputPath * @param ostream * @return * @throws InvalidFormatException * @throws FileNotFoundException * @throws IOException */private ByteArrayOutputStream readWordDocument(Map<String, Object> map, String outputPath, ByteArrayOutputStream ostream) throws InvalidFormatException, FileNotFoundException, IOException { // replace the text of header if (document.getHeaderList() != null && document.getHeaderList().size() > 0) { XWPFHeader header = document.getHeaderArray(0); List<XWPFParagraph> listHeader = header.getParagraphs(); for (XWPFParagraph paragraph : listHeader) { replaceWordText(paragraph, map); } } // replace the text of body Iterator<XWPFParagraph> itPara = document.getParagraphsIterator(); while (itPara.hasNext()) { XWPFParagraph paragraph = itPara.next(); replaceWordText(paragraph, map); // wordReadRule.addPictureInWord(document); } // replace the text of table Iterator<XWPFTable> itTable = document.getTablesIterator(); while (itTable.hasNext()) { XWPFTable table = itTable.next(); readWordTableRangeRule(table, map); } //判断文件夹是否存在不存在, 则创建 String tmp = CacheLoader.webroot + "exportword"; File file = new File(tmp); if(!file.exists()) { file.mkdir(); } File newfile = new File(outputPath); if(newfile.exists()) { newfile.delete(); } FileOutputStream fos = new FileOutputStream(newfile); document.write(fos); ostream = new ByteArrayOutputStream(); document.write(ostream); return ostream;}/** * Read Word Table Range Rule * @param table * @param mapProperties * 解析文档中的关键字以及通配符 */private void readWordTableRangeRule(XWPFTable table, Map<String, Object> mapProperties) { List<Map<String, String>> hasCellContant = new ArrayList<Map<String, String>>(); int rcount = table.getNumberOfRows(); boolean isListValue = false; boolean noSN = false; for (int i = 0; i < rcount; i++) { XWPFTableRow row = table.getRow(i); List<XWPFTableCell> cells = row.getTableCells(); for (int j = 0; j < cells.size(); j++) { XWPFTableCell cell = cells.get(j); String cellTextString = cell.getText(); for (Map.Entry<String, Object> entry : mapProperties.entrySet()) { String paramName = EL_LEFT + entry.getKey() + EL_RIGHT; if (cellTextString.contains(paramName)) { String replaceText = ""; if (entry.getValue() instanceof List) { if (getNoSNTable().contains(entry.getKey())) { noSN = true; } List<Map<String, String>> list = (List<Map<String, String>>)entry.getValue(); hasCellContant.addAll(list); isListValue = true; } else { if (null != entry.getValue()) { replaceText = String.valueOf(entry.getValue()); } } repalceText(cell, paramName, replaceText); if (isListValue) break; } } if (isListValue) break; } if (isListValue) break; } if (isListValue) addListValueInTable(hasCellContant, table, noSN);}/** * table写入 * @param hasCellContant * @param table * @param noSN */private void addListValueInTable(List<Map<String, String>> hasCellContant, XWPFTable table, boolean noSN) { //add text of list values in table Map<Integer, List<String>> insertTextIndex = new HashMap<Integer, List<String>>(); if (hasCellContant.size() > 0) { for (int i = 0; i < hasCellContant.size(); i++) { XWPFTableRow row = null; List<XWPFTableCell> cells = null; Map<String, String> map = hasCellContant.get(i); if (i == 0) { row = table.getRow(1); } else { row = table.createRow(); } cells = row.getTableCells(); for (int j = 0; j < cells.size(); j++) { XWPFTableCell cell = cells.get(j); String text = cell.getText(); if (j == 0 && i > 0) { if (!noSN) { text = String.valueOf(i + 1); } } else if (j != 0) { List<String> listParamNames = new ArrayList<String>(); for (Map.Entry<String, String> entry : map.entrySet()) { String paramName = EL_LEFT + entry.getKey() + EL_RIGHT; if (i == 0) { if (text.contains(paramName)) { text =
text.replace(paramName, entry.getValue());
listParamNames.add(entry.getKey());
}
} else {
listParamNames = insertTextIndex.get(j);
for (String name : listParamNames) {
if (name.equals(entry.getKey())) {
text += entry.getValue();
}
}
}
}
if (i == 0) {
insertTextIndex.put(j, listParamNames);
}
}
if (i == 0 && j != 0) {
cell.removeParagraph(0);
}
if (!(i == 0 && j == 0)) {
cell.setText(text);
}
}
}
}
}
/** * replace text and images * @param paragraph * @param mapProperties * @throws InvalidFormatException * @throws FileNotFoundException */private void replaceWordText(XWPFParagraph paragraph, Map<String, Object> mapProperties) throws InvalidFormatException, FileNotFoundException { List<XWPFRun> runs = paragraph.getRuns(); for (int i = 0; i < runs.size(); i++) { XWPFRun run = runs.get(i); String oneparaString = run.getText(run.getTextPosition()); if (null != oneparaString) { for (Map.Entry<String, Object> entry : mapProperties.entrySet()) { boolean isImage = entry.getKey().startsWith(IMAGE_); String paramName = EL_LEFT + entry.getKey() + EL_RIGHT; if (!isImage) { if (oneparaString.contains(paramName)) { String replaceText = ""; if (null != entry.getValue()) { replaceText = String.valueOf(entry.getValue()); } oneparaString = oneparaString.replace(paramName, replaceText); } } else if (isImage) { if (oneparaString.contains(paramName.replace(IMAGE_, ""))) { oneparaString = ""; CTInline inline = run.getCTR().addNewDrawing().addNewInline(); insertPicture(document, String.valueOf(entry.getValue()), inline, 100, 100); } } } run.setText(oneparaString, 0); } }}/** * insert Picture * @param document * @param filePath * @param inline * @param width * @param height * @throws InvalidFormatException * @throws FileNotFoundException */private void insertPicture(XWPFDocument document, String filePath, CTInline inline, int width, int height) throws InvalidFormatException, FileNotFoundException { document.addPictureData(new FileInputStream(filePath), XWPFDocument.PICTURE_TYPE_PNG); int id = document.getAllPictures().size() - 1; final int EMU = 9525; width *= EMU; height *= EMU; String blipId = document.getAllPictures().get(id).getPackageRelationship().getId(); String picXml = getPicXml(blipId, width, height); 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("IMG_" + id); docPr.setDescr("IMG_" + id);}private void repalceText(XWPFTableCell cell, String paramName, String replaceText) { if (null != cell.getParagraphs()) { int lengthOld = cell.getParagraphs().size(); for (int i = 0; i < lengthOld; i++) { XWPFParagraph xWPFParagraph = cell.getParagraphs().get(i); for (int j = 0; j < xWPFParagraph.getCTP().getRArray().length; j++) { CTR run = xWPFParagraph.getCTP().getRArray()[j]; for (int k = 0; k < run.getTArray().length; k++) { CTText text = run.getTArray()[k]; String stringValue = text.getStringValue(); if (stringValue.contains(paramName)) { stringValue = stringValue.replace(paramName, replaceText); text.setStringValue(stringValue); } } } } }}/** * get the xml of the picture * @param blipId * @param width * @param height * @return */private String getPicXml(String blipId, int width, int height) { 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=\"" + 0 + "\" 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>"; return picXml;}public void setNoSNTable(List<String> noSNTable) { this.noSNTable = noSNTable;}public List<String> getNoSNTable() { if (null == noSNTable) { noSNTable = new ArrayList<String>(); } return noSNTable;}
}
ByteArrayOutputStream ostream = wordUtil.generateWordFromTemplate(templateUrl, outUrl, params, ostream);
// 输出 word 内容文件流,提供下载
response.reset();
response.setContentType(“application/x-msdownload”);
// 随机生成一个文件名 response.addHeader("Content-Disposition", "attachment; filename=\""+ fileName); servletOS.write(ostream.toByteArray()); servletOS.flush();
生成word进行下载,poi架包
- 文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题 文章标题 文章标题 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 过滤器、监听器、拦截器的区别和一个简单的实例
- 安卓ViewPager使用注意小计
- UDP发广播给所有网卡(包含虚拟网卡)
- 他们是如何通过写娱乐八卦来赚钱的
- caffe 实验中输入数据和label都是图片时,训练或测试数据列表train.txt生成方法(linux指令总结)
- 文章标题
- 单点登录原理与简单实现
- 关于router的坑
- JS 实现跨域模拟登入
- 一款用于表格数据自定义排序的jQuery插件jquery.tablesortable.js(附ajax例子)
- tcpdump 很详细的
- 使用 Node.js 與 Socket.IO 建立即時性(Realtime)網頁應用程式 App
- 第十五周9
- 【异常】自定义异常