在此记录折磨了我三天的垃圾功能哈哈
advice:如果你在为java操作word做技术选型,墙裂不推荐用POI!!!!!!!别问为什么。。。。
导入依赖
···
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-examples --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-examples</artifactId><version>3.17</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-excelant --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-excelant</artifactId><version>3.17</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas --><!-- 这个是我注释掉的,不知道啥东西,缺少jar包依赖,抱什么错忘记了,就是想用的类依赖无法导入,所以被我直接干掉 --><!-- <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.17</version></dependency> --><!-- 这个包的存在就是为了替换上面被我去掉的jar,百度了一下,传说这个包比上面的包类更全些,实测确实有我需要的东西,在此1.3和其他的3.17是否良好兼容存在疑问 --><dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.3</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>3.17</version></dependency><!-- 条码 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.3</version></dependency>
感觉不是太难,以为很快就可以做完,结果发现office2016存在兼容行问题,显示的奇丑无比,emmm,于是。。。一百万年后。。。。
一个controller
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.BreakType;
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.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation;@RequestMapping(value="/printAll")public void printAll(HttpServletResponse response) throws Exception{
HttpServletRequest rt=this.getRequest();InputStream tempFileInputStream = null;ByteArrayOutputStream bout = null;OutputStream outputStream = null;String realpath = rt.getSession().getServletContext().getRealPath("/uploadFiles/file"); realpath=realpath.replaceAll("\\\\","\\\\\\\\"); String filePath=realpath+"\\"+"\\process_card_print_template.docx";///模板的物理路径XWPFHelperTable ht = new XWPFHelperTable();XWPFHelper h = new XWPFHelper();PageData pd = new PageData();pd = this.getPageData();try {
tempFileInputStream = new FileInputStream(new File(filePath));XWPFDocument document = new XWPFDocument(tempFileInputStream);XWPFTable table = ht.getTableByIndex(document, 0);List<PageData> varList = process_cardService.listAll(pd);//取到你自己想要的数据,这行忽略bout = new ByteArrayOutputStream(); document = new XWPFDocument();h.setDocumentMargin(document, "300", "300", "300", "300");//设置页边距//h.createDefaultHeader(document,"卡片");//设置页眉for(int j=0;j<varList.size();j++) {
XWPFParagraph title = document.createParagraph();XWPFRun run = title.createRun();run.setText("卡片");run.setBold(true);run.setFontSize(20);BufferedImage image = BarCodeUtil.getBarCode(varList.get(j).get("BAR_CODE").toString());//这个是一个图片内容的数据源,可以忽略bout = new ByteArrayOutputStream();ImageIO.write(image, "png", bout);tempFileInputStream = new ByteArrayInputStream(bout.toByteArray());run.addPicture(tempFileInputStream, XWPFDocument.PICTURE_TYPE_JPEG, "barcode.jpg", Units.toEMU(180), Units.toEMU(20));//写个图片,传说单位只能是emu没有具体验证过哈哈title.setAlignment(ParagraphAlignment.CENTER);XWPFTable realTable = document.createTable(8, 8);h.copyTable(realTable,table);//拷贝模板List<XWPFTableRow> rowList = realTable.getRows();//第一行rowList.get(0).getTableCells().get(1).getParagraphArray(0).createRun().setText(varList.get(j).get("PRODUCTION_ORDER_NO").toString());rowList.get(0).getTableCells().get(3).getParagraphArray(0).createRun().setText(varList.get(j).get("PROJECT_NO").toString());rowList.get(0).getTableCells().get(5).getParagraphArray(0).createRun().setText(varList.get(j).get("PLAN_NO").toString());rowList.get(0).getTableCells().get(7).getParagraphArray(0).createRun().setText(varList.get(j).get("CONSTRUCTION_PERIOD").toString());//第二行rowList.get(1).getTableCells().get(1).getParagraphArray(0).createRun().setText(varList.get(j).get("PRODUCT_NAME").toString());rowList.get(1).getTableCells().get(3).getParagraphArray(0).createRun().setText(varList.get(j).get("PRODUCT_DRAWING_NO").toString());rowList.get(1).getTableCells().get(5).getParagraphArray(0).createRun().setText(varList.get(j).get("FQTY").toString());ht.delCell(realTable, 1, 7);ht.delCell(realTable, 1, 6);//第三行ht.delCell(realTable, 2, 7);//第四行rowList.get(3).getTableCells().get(0).getParagraphArray(0).createRun().setText(varList.get(j).get("FNAME").toString());rowList.get(3).getTableCells().get(1).getParagraphArray(0).createRun().setText(varList.get(j).get("DRAWING_NO").toString());rowList.get(3).getTableCells().get(2).getParagraphArray(0).createRun().setText(varList.get(j).get("UNITQTY_AND_SETSQTY").toString());rowList.get(3).getTableCells().get(3).getParagraphArray(0).createRun().setText(varList.get(j).get("MAT_CODE").toString());rowList.get(3).getTableCells().get(4).getParagraphArray(0).createRun().setText(varList.get(j).get("MAT_SPEC").toString());rowList.get(3).getTableCells().get(5).getParagraphArray(0).createRun().setText(varList.get(j).get("DIMENSION_AND_FACTOR").toString());rowList.get(3).getTableCells().get(6).getParagraphArray(0).createRun().setText(varList.get(j).get("SINGLE_BLANK_PARTS").toString());ht.delCell(realTable, 3, 7);//第五行ht.delCell(realTable, 4, 7);ht.delCell(realTable, 4, 6);//这里是工序列表List<PageData> mxList = process_cardmxService.listAll(varList.get(j));for(int i=0;i<mxList.size();i++) {
if(i<mxList.size()-1) {
XWPFHelperTable.insertRow(realTable, i+6, i+7);}realTable.getRow(i+6).getCell(0).setText(mxList.get(i).get("STAGES_NO").toString());realTable.getRow(i+6).getCell(1).setText(mxList.get(i).get("STAGES_NAME").toString());realTable.getRow(i+6).getCell(2).setText(mxList.get(i).get("STAGES_CONTENT").toString());realTable.getRow(i+6).getCell(3).setText(mxList.get(i).get("STAGES_EQM").toString());realTable.getRow(i+6).getCell(4).setText(mxList.get(i).get("MAN_HOUR_PER_SETS").toString());}//最后一行XWPFTableRow lastrow = rowList.get(rowList.size()-1);//复制列对象,加三个单元格,将表格右下角补齐lastrow.addNewTableCell();lastrow.addNewTableCell();lastrow.addNewTableCell();// 跨列合并,合并成六列 表, 所合并的行 , 起始列 , 终止列ht.mergeCellsHorizontal(realTable, rowList.size()-1, 0, 1);ht.mergeCellsHorizontal(realTable, rowList.size()-1, 4, 5);ht.mergeCellsHorizontal(realTable, rowList.size()-1, 6, 8);ht.mergeCellsHorizontal(realTable, rowList.size()-1, 9, 10);lastrow.getCell(0).setText("编制:");lastrow.getCell(2).setText(varList.get(j).get("DOCUMENT_MAKER").toString());lastrow.getCell(3).setText("定额:");lastrow.getCell(4).setText(varList.get(j).get("QUOTA_PERSON").toString());lastrow.getCell(6).setText("审核:");lastrow.getCell(9).setText(varList.get(j).get("FREVIEWER").toString());ht.setTextCenter(lastrow);//设置一行文本水平垂直居中ht.setTableLocation(realTable, "center");//设置表格居中ht.setOrient(document,STPageOrientation.LANDSCAPE);// 设置文档横版h.createDefaultFooter(document);//设置页码if(j<varList.size()-1) {
document.createParagraph().createRun().addBreak(BreakType.PAGE);}}//导出到文件bout = new ByteArrayOutputStream();document.write(bout);response.reset(); String fileName = varList.get(0).get("PRODUCT_NAME").toString()+Tools.date2Str(new Date());fileName = URLEncoder.encode(fileName, "UTF-8");response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".docx\""); response.addHeader("Content-Length", "" + bout.toByteArray().length); response.setContentType("application/octet-stream;charset=UTF-8"); outputStream = new BufferedOutputStream(response.getOutputStream()); outputStream.write(bout.toByteArray());outputStream.flush();response.flushBuffer();} catch (Exception e) {
e.printStackTrace();} finally {
if (tempFileInputStream != null){
try {
tempFileInputStream.close();} catch (IOException e) {
e.printStackTrace();}}if (bout != null){
try {
bout.close();} catch (IOException e) {
e.printStackTrace();}}if (outputStream != null){
try {
outputStream.close();} catch (IOException e) {
e.printStackTrace();}}}}
工具类,这两个类都是网上抄来的,忘记出处了,看好多地方都有。。。。
package org.yy.util.poi;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.List;
import java.util.logging.Level;
import java.util.logging.Logger;import org.apache.commons.lang.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TextAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.poi.xwpf.usermodel.XWPFRelation;
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.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
import org.yy.util.poi.ParagraphStyle;
import org.yy.util.poi.TextStyle;/*** @Description 设置docx文档的样式及一些操作 * @Author Huangxiaocong* 2018年12月1日 下午12:18:41* 基本概念说明:XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档* XWPFParagraph代表文档、表格、标题等种的段落,由多个XWPFRun组成* XWPFRun代表具有同样风格的一段文本* XWPFTable代表一个表格* XWPFTableRow代表表格的一行* XWPFTableCell代表表格的一个单元格 * XWPFChar 表示.docx文件中的图表* XWPFHyperlink 表示超链接* XWPFPicture 代表图片* * 注意:直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun。*/
public class XWPFHelper {
private static Logger logger = Logger.getLogger(XWPFHelper.class.toString());/*** 创建一个word对象* @return* @Author Huangxiaocong 2018年12月1日 上午11:56:35*/public XWPFDocument createDocument() {
XWPFDocument document = new XWPFDocument();return document;}/*** 打开word文档* @param path 文档所在路径* @return* @throws IOException* @Author Huangxiaocong 2018年12月1日 下午12:30:07*/public XWPFDocument openDoc(String path) throws IOException {
InputStream is = new FileInputStream(path);return new XWPFDocument(is);}/*** 保存word文档* @param document 文档对象* @param savePath 保存路径* @throws IOException* @Author Huangxiaocong 2018年12月1日 下午12:32:37*/public void saveDocument(XWPFDocument document, String savePath) throws IOException {
OutputStream os = new FileOutputStream(savePath);document.write(os);os.close();}/*** 设置段落文本样式 设置超链接及样式* @param paragraph* @param textStyle* @param url* @Author Huangxiaocong 2018年12月1日 下午3:56:32*/public void addParagraphTextHyperlink(XWPFParagraph paragraph, TextStyle textStyle) {
String id = paragraph.getDocument().getPackagePart().addExternalRelationship(textStyle.getUrl(),XWPFRelation.HYPERLINK.getRelation()).getId();//追加链接并将其绑定到关系中CTHyperlink cLink = paragraph.getCTP().addNewHyperlink();cLink.setId(id);//创建链接文本CTText ctText = CTText.Factory.newInstance();ctText.setStringValue(textStyle.getText());CTR ctr = CTR.Factory.newInstance();CTRPr rpr = ctr.addNewRPr();//以下设置各种样式 详情看TextStyle类if(textStyle.getFontFamily() != "" && textStyle.getFontFamily() != null ) {
CTFonts fonts = rpr.isSetRFonts() ? rpr.getRFonts() : rpr.addNewRFonts();fonts.setAscii(textStyle.getFontFamily());//...}//设置字体大小}/*** 设置段落的基本样式 设置段落间距信息, 一行 = 100 一磅=20 * @param paragraph* @param paragStyle* @Author Huangxiaocong 2018年12月1日 下午4:27:17*/public void setParagraphSpacingInfo(XWPFParagraph paragraph, ParagraphStyle paragStyle, STLineSpacingRule.Enum lineValue) {
CTPPr pPPr = getParagraphCTPPr(paragraph);CTSpacing pSpacing = pPPr.getSpacing() != null ? pPPr.getSpacing() : pPPr.addNewSpacing();if(paragStyle.isSpace()) {
//段前磅数if(paragStyle.getBefore() != null) {
pSpacing.setBefore(new BigInteger(paragStyle.getBefore()));}//段后磅数if(paragStyle.getAfter() != null) {
pSpacing.setAfter(new BigInteger(paragStyle.getAfter()));}//依次设置段前行数、段后行数//...}//间距if(paragStyle.isLine()) {
if(paragStyle.getLine() != null) {
pSpacing.setLine(new BigInteger(paragStyle.getLine()));}if(lineValue != null) {
pSpacing.setLineRule(lineValue); //}}}/*** 设置段落缩进信息 1厘米 约等于 567* @param paragraph* @param paragStyle* @Author Huangxiaocong 2018年12月1日 下午7:59:35*/public void setParagraphIndInfo(XWPFParagraph paragraph, ParagraphStyle paragStyle) {
CTPPr pPPr = getParagraphCTPPr(paragraph);CTInd pInd = pPPr.getInd() != null ? pPPr.getInd() : pPPr.addNewInd();if(paragStyle.getFirstLine() != null) {
pInd.setFirstLine(new BigInteger(paragStyle.getFirstLine()));}//再进行其他设置//...}/*** 设置段落对齐 方式* @param paragraph* @param pAlign* @param valign* @Author Huangxiaocong 2018年12月1日 下午8:54:43*/public void setParagraphAlignInfo(XWPFParagraph paragraph, ParagraphAlignment pAlign, TextAlignment valign) {
if(pAlign != null) {
paragraph.setAlignment(pAlign);}if(valign != null) {
paragraph.setVerticalAlignment(valign);}}/*** 得到段落的CTPPr* @param paragraph* @return* @Author Huangxiaocong 2018年12月1日 下午7:36:10*/public CTPPr getParagraphCTPPr(XWPFParagraph paragraph) {
CTPPr pPPr = null;if(paragraph.getCTP() != null) {
if(paragraph.getCTP().getPPr() != null) {
pPPr = paragraph.getCTP().getPPr();} else {
pPPr = paragraph.getCTP().addNewPPr();}}return pPPr;}/*** 得到XWPFRun的CTRPr* @param paragraph* @param pRun* @return* @Author Huangxiaocong 2018年12月1日 下午7:46:01*/public CTRPr getRunCTRPr(XWPFParagraph paragraph, XWPFRun pRun) {
CTRPr ctrPr = null;if(pRun.getCTR() != null) {
ctrPr = pRun.getCTR().getRPr();if(ctrPr == null) {
ctrPr = pRun.getCTR().addNewRPr();}} else {
ctrPr = paragraph.getCTP().addNewR().addNewRPr();}return ctrPr;}/*** 复制表格* @param targetTable* @param sourceTable* @Author Huangxiaocong 2018年12月1日 下午1:40:01*/public void copyTable(XWPFTable targetTable, XWPFTable sourceTable) {
//复制表格属性targetTable.getCTTbl().setTblPr(sourceTable.getCTTbl().getTblPr());//复制行for(int i = 0; i < sourceTable.getRows().size(); i++) {
XWPFTableRow targetRow = targetTable.getRow(i);XWPFTableRow sourceRow = sourceTable.getRow(i);if(targetRow == null) {
targetTable.addRow(sourceRow);} else {
copyTableRow(targetRow, sourceRow);}}}/*** 复制单元格* @param targetRow* @param sourceRow* @Author Huangxiaocong 2018年12月1日 下午1:33:22*/public void copyTableRow(XWPFTableRow targetRow, XWPFTableRow sourceRow) {
List<XWPFTableCell> cells = targetRow.getTableCells();List<XWPFTableCell> cells1 = sourceRow.getTableCells();//复制样式if(sourceRow != null) {
targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());}//复制单元格for(int i = 0; i < sourceRow.getTableCells().size(); i++) {
XWPFTableCell tCell = targetRow.getCell(i);XWPFTableCell sCell = sourceRow.getCell(i);if(tCell == sCell) {
tCell = targetRow.addNewTableCell();}copyTableCell(tCell, sCell);}}/*** 复制单元格(列) 从sourceCell到targetCell* @param targetCell* @param sourceCell* @Author Huangxiaocong 2018年12月1日 下午1:27:38*/public void copyTableCell(XWPFTableCell targetCell, XWPFTableCell sourceCell) {
//表格属性if(sourceCell.getCTTc() != null) {
targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());}//删除段落for(int pos = 0; pos < targetCell.getParagraphs().size(); pos++) {
targetCell.removeParagraph(pos);}//添加段落for(XWPFParagraph sourceParag : sourceCell.getParagraphs()) {
XWPFParagraph targetParag = targetCell.addParagraph();copyParagraph(targetParag, sourceParag);}}/*** 复制段落,从sourceParag到targetParag* @param targetParag* @param sourceParag* @Author Huangxiaocong 2018年12月1日 下午1:16:26*/public void copyParagraph(XWPFParagraph targetParag, XWPFParagraph sourceParag) {
targetParag.getCTP().setPPr(sourceParag.getCTP().getPPr()); //设置段落样式//移除所有的runfor(int pos = targetParag.getRuns().size() - 1; pos >= 0; pos-- ) {
targetParag.removeRun(pos);}//copy新的runfor(XWPFRun sRun : sourceParag.getRuns()) {
XWPFRun tarRun = targetParag.createRun();copyRun(tarRun, sRun);}}/*** 复制XWPFRun 从sourceRun到targetRun* @param targetRun* @param sourceRun* @Author Huangxiaocong 2018年12月1日 下午12:56:53*/public void copyRun(XWPFRun targetRun, XWPFRun sourceRun) {
//设置targetRun属性targetRun.getCTR().setRPr(sourceRun.getCTR().getRPr());targetRun.setText(sourceRun.text());//设置文本//处理图片List<XWPFPicture> pictures = sourceRun.getEmbeddedPictures();for(XWPFPicture picture : pictures) {
try {
copyPicture(targetRun, picture);} catch (InvalidFormatException e) {
e.printStackTrace();logger.log(Level.WARNING, "copyRun", e);} catch (IOException e) {
e.printStackTrace();logger.log(Level.WARNING, "copyRun", e);}}}/*** 复制图片从sourcePicture到 targetRun(XWPFPicture --> XWPFRun)* @param targetRun* @param source* @throws IOException * @throws InvalidFormatException * @Author Huangxiaocong 2018年12月1日 下午12:57:33*/public void copyPicture(XWPFRun targetRun, XWPFPicture sourcePicture) throws InvalidFormatException, IOException {
XWPFPictureData picData = sourcePicture.getPictureData();String fileName = picData.getFileName(); //图片的名称InputStream picInIsData = new ByteArrayInputStream(picData.getData()); int picType = picData.getPictureType();int width = (int) sourcePicture.getCTPicture().getSpPr().getXfrm().getExt().getCx();int height = (int) sourcePicture.getCTPicture().getSpPr().getXfrm().getExt().getCy();targetRun.addPicture(picInIsData, picType, fileName, width, height);
// targetRun.addBreak();//分行}/*** 设置页边距 (word中1厘米约等于567) * @param document* @param left* @param top* @param right* @param bottom*/public void setDocumentMargin(XWPFDocument document, String left,String top, String right, String bottom) {
CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();CTPageMar ctpagemar = sectPr.addNewPgMar();if (StringUtils.isNotBlank(left)) {
ctpagemar.setLeft(new BigInteger(left)); } if (StringUtils.isNotBlank(top)) {
ctpagemar.setTop(new BigInteger(top)); } if (StringUtils.isNotBlank(right)) {
ctpagemar.setRight(new BigInteger(right)); } if (StringUtils.isNotBlank(bottom)) {
ctpagemar.setBottom(new BigInteger(bottom)); } }/*** 创建默认页眉** @param docx XWPFDocument文档对象* @param text 页眉文本* @return 返回文档帮助类对象,可用于方法链调用* @throws XmlException XML异常* @throws IOException IO异常* @throws InvalidFormatException 非法格式异常* @throws FileNotFoundException 找不到文件异常*/public void createDefaultHeader(final XWPFDocument docx, final String text){
CTP ctp = CTP.Factory.newInstance();XWPFParagraph paragraph = new XWPFParagraph(ctp, docx);ctp.addNewR().addNewT().setStringValue(text);ctp.addNewR().addNewT().setSpace(SpaceAttribute.Space.PRESERVE);CTSectPr sectPr = docx.getDocument().getBody().isSetSectPr() ? docx.getDocument().getBody().getSectPr() : docx.getDocument().getBody().addNewSectPr();XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(docx, sectPr);XWPFHeader header = policy.createHeader(STHdrFtr.DEFAULT, new XWPFParagraph[] {
paragraph });header.setXWPFDocument(docx);}/*** 创建默认的页脚(该页脚主要只居中显示页码)* * @param docx* XWPFDocument文档对象* @return 返回文档帮助类对象,可用于方法链调用* @throws XmlException* XML异常* @throws IOException* IO异常*/public void createDefaultFooter(final XWPFDocument docx) {
// 设置页码起始值CTP pageNo = CTP.Factory.newInstance();XWPFParagraph footer = new XWPFParagraph(pageNo, docx);CTPPr begin = pageNo.addNewPPr();begin.addNewPStyle().setVal("footer");begin.addNewJc().setVal(STJc.CENTER);pageNo.addNewR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);pageNo.addNewR().addNewInstrText().setStringValue("PAGE \\* MERGEFORMAT");pageNo.addNewR().addNewFldChar().setFldCharType(STFldCharType.SEPARATE);CTR end = pageNo.addNewR();CTRPr endRPr = end.addNewRPr();endRPr.addNewNoProof();endRPr.addNewLang().setVal("zh-CN");end.addNewFldChar().setFldCharType(STFldCharType.END);CTSectPr sectPr = docx.getDocument().getBody().isSetSectPr() ? docx.getDocument().getBody().getSectPr() : docx.getDocument().getBody().addNewSectPr();XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(docx, sectPr);policy.createFooter(STHdrFtr.DEFAULT, new XWPFParagraph[] {
footer });}}
package org.yy.util.poi;import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;import org.apache.poi.xwpf.usermodel.BodyElementType;
import org.apache.poi.xwpf.usermodel.IBodyElement;
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.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;/*** @Description 操作word的基本工具类* 2018年12月3日 上午11:12:18* @Author Huangxiaocong*/
public class XWPFHelperTable {
public void setTextCenter(XWPFTableRow row) {
//XWPFTableCell cellfor(int i=0;i<row.getTableCells().size();i++) {
XWPFTableCell cell = row.getTableCells().get(i);cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); //垂直居中CTTc cttc = cell.getCTTc();CTP ctp = cttc.getPList().get(0);CTPPr ctppr = ctp.getPPr();if (ctppr == null) {
ctppr = ctp.addNewPPr();}CTJc ctjc = ctppr.getJc();if (ctjc == null) {
ctjc = ctppr.addNewJc();}ctjc.setVal(STJc.CENTER); //水平居中}}/*** 设置文档大小为A4纸规格,设置横版、竖版,不设置情况下默认竖版* @param document* @param e 枚举:STPageOrientation.PORTRAIT 竖版;* STPageOrientation.LANDSCAPE 横版;*/public void setOrient(XWPFDocument document,STPageOrientation.Enum e) {
CTDocument1 document1 = document.getDocument();//设置页面横向CTBody body = document1.getBody();if (!body.isSetSectPr()) {
body.addNewSectPr();}CTSectPr section = body.getSectPr();section.addNewPgSz();if(!section.isSetPgSz()) {
section.addNewPgSz();}CTPageSz pageSize = section.getPgSz();//必须要设置下面两个参数,否则整个的代码是无效的,首先1英寸=2.54厘米,A4纸大小为21cm*29.7cm。如果这个width设置成5670,则表示这个表格的宽度是10cm。pageSize.setW(BigInteger.valueOf(16840));// ≈29.7cmpageSize.setH(BigInteger.valueOf(11907));// ≈21cmpageSize.setOrient(e);}/*** 删除单元格* @param table XWPFTable* @param row 行号* @param col 列号*/public void delCell(XWPFTable table, int row, int col) {
XWPFTableCell removed = table.getRows().get(row).getCell(col);removed.getCTTc().newCursor().removeXml();table.getRows().get(row).removeCell(col);}/*** 设置表格位置** @param xwpfTable* @param location 整个表格居中center,left居左,right居右,both两端对齐*/public void setTableLocation(XWPFTable xwpfTable, String location) {
CTTbl cttbl = xwpfTable.getCTTbl();CTTblPr tblpr = cttbl.getTblPr() == null ? cttbl.addNewTblPr() : cttbl.getTblPr();CTJc cTJc = tblpr.addNewJc();cTJc.setVal(STJc.Enum.forString(location));}/*** 设置单元格水平位置和垂直位置** @param xwpfTable* @param verticalLoction 单元格中内容垂直上TOP,下BOTTOM,居中CENTER,BOTH两端对齐* @param horizontalLocation 单元格中内容水平居中center,left居左,right居右,both两端对齐*/public void setCellLocation(XWPFTable xwpfTable, String verticalLoction, String horizontalLocation) {
List<XWPFTableRow> rows = xwpfTable.getRows();for (XWPFTableRow row : rows) {
List<XWPFTableCell> cells = row.getTableCells();for (XWPFTableCell cell : cells) {
CTTc cttc = cell.getCTTc();CTP ctp = cttc.getPList().get(0);CTPPr ctppr = ctp.getPPr();if (ctppr == null) {
ctppr = ctp.addNewPPr();}CTJc ctjc = ctppr.getJc();if (ctjc == null) {
ctjc = ctppr.addNewJc();}ctjc.setVal(STJc.Enum.forString(horizontalLocation)); //水平居中cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.valueOf(verticalLoction));//垂直居中}}}/*** insertRow 在word表格中指定位置插入一行,并将某一行的样式复制到新增行* @param copyrowIndex 需要复制的行位置* @param newrowIndex 需要新增一行的位置* */public static void insertRow(XWPFTable table, int copyrowIndex, int newrowIndex) {
// 在表格中指定的位置新增一行XWPFTableRow targetRow = table.insertNewTableRow(newrowIndex);// 获取需要复制行对象XWPFTableRow copyRow = table.getRow(copyrowIndex);//复制行对象targetRow.getCtRow().setTrPr(copyRow.getCtRow().getTrPr());//或许需要复制的行的列List<XWPFTableCell> copyCells = copyRow.getTableCells();//复制列对象XWPFTableCell targetCell = null;for (int i = 0; i < copyCells.size(); i++) {
XWPFTableCell copyCell = copyCells.get(i);targetCell = targetRow.addNewTableCell();targetCell.getCTTc().setTcPr(copyCell.getCTTc().getTcPr());if (copyCell.getParagraphs() != null && copyCell.getParagraphs().size() > 0) {
targetCell.getParagraphs().get(0).getCTP().setPPr(copyCell.getParagraphs().get(0).getCTP().getPPr());if (copyCell.getParagraphs().get(0).getRuns() != null&& copyCell.getParagraphs().get(0).getRuns().size() > 0) {
XWPFRun cellR = targetCell.getParagraphs().get(0).createRun();cellR.setBold(copyCell.getParagraphs().get(0).getRuns().get(0).isBold());} } }}/*** 删除指定位置的表格,被删除表格后的索引位置* @param document* @param pos* @Author Huangxiaocong 2018年12月1日 下午10:32:43*/public void deleteTableByIndex(XWPFDocument document, int pos) {
Iterator<IBodyElement> bodyElement = document.getBodyElementsIterator();int eIndex = 0, tableIndex = -1;while(bodyElement.hasNext()) {
IBodyElement element = bodyElement.next();BodyElementType elementType = element.getElementType();if(elementType == BodyElementType.TABLE) {
tableIndex++;if(tableIndex == pos) {
break;}}eIndex++;}document.removeBodyElement(eIndex);}/*** 获得指定位置的表格* @param document* @param index* @return* @Author Huangxiaocong 2018年12月1日 下午10:34:14*/public XWPFTable getTableByIndex(XWPFDocument document, int index) {
List<XWPFTable> tableList = document.getTables();if(tableList == null || index < 0 || index > tableList.size()) {
return null;}return tableList.get(index);}/*** 得到表格的内容(第一次跨行单元格视为一个,第二次跳过跨行合并的单元格)* @param table* @return* @Author Huangxiaocong 2018年12月1日 下午10:46:41*/public List<List<String>> getTableRConten(XWPFTable table) {
List<List<String>> tableContextList = new ArrayList<List<String>>();for(int rowIndex = 0, rowLen = table.getNumberOfRows(); rowIndex < rowLen; rowIndex++) {
XWPFTableRow row = table.getRow(rowIndex);List<String> cellContentList = new ArrayList<String>();for(int colIndex = 0, colLen = row.getTableCells().size(); colIndex < colLen; colIndex++ ) {
XWPFTableCell cell = row.getCell(colIndex);CTTc ctTc = cell.getCTTc();if(ctTc.isSetTcPr()) {
CTTcPr tcPr = ctTc.getTcPr();if(tcPr.isSetHMerge()) {
CTHMerge hMerge = tcPr.getHMerge();if(STMerge.RESTART.equals(hMerge.getVal())) {
cellContentList.add(getTableCellContent(cell));}} else if(tcPr.isSetVMerge()) {
CTVMerge vMerge = tcPr.getVMerge();if(STMerge.RESTART.equals(vMerge.getVal())) {
cellContentList.add(getTableCellContent(cell));}} else {
cellContentList.add(getTableCellContent(cell));}}}tableContextList.add(cellContentList);}return tableContextList;}/*** 获得一个表格的单元格的内容* @param cell* @return* @Author Huangxiaocong 2018年12月2日 下午7:39:23*/public String getTableCellContent(XWPFTableCell cell) {
StringBuffer sb = new StringBuffer();List<XWPFParagraph> cellParagList = cell.getParagraphs();if(cellParagList != null && cellParagList.size() > 0) {
for(XWPFParagraph xwpfPr: cellParagList) {
List<XWPFRun> runs = xwpfPr.getRuns();if(runs != null && runs.size() > 0) {
for(XWPFRun xwpfRun : runs) {
sb.append(xwpfRun.getText(0));}}}}return sb.toString();}/*** 得到表格内容,合并后的单元格视为一个单元格* @param table* @return* @Author Huangxiaocong 2018年12月2日 下午7:47:19*/public List<List<String>> getTableContent(XWPFTable table) {
List<List<String>> tableContentList = new ArrayList<List<String>>();for (int rowIndex = 0, rowLen = table.getNumberOfRows(); rowIndex < rowLen; rowIndex++) {
XWPFTableRow row = table.getRow(rowIndex);List<String> cellContentList = new ArrayList<String>();for (int colIndex = 0, colLen = row.getTableCells().size(); colIndex < colLen; colIndex++) {
XWPFTableCell cell = row.getCell(colIndex);cellContentList.add(getTableCellContent(cell));}tableContentList.add(cellContentList);}return tableContentList;}/*** 得到Cell的CTTcPr,不存在则新建* @param cell XWPFTableCell* @return*/public static CTTcPr getCellCTTcPr(XWPFTableCell cell) {
CTTc cttc = cell.getCTTc();CTTcPr tcPr = cttc.isSetTcPr() ? cttc.getTcPr() : cttc.addNewTcPr();return tcPr;}/*** 跨列合并* @param table* @param row 所合并的行* @param fromCell 起始列* @param toCell 终止列* @Description* @Author Huangxiaocong 2018年11月26日 下午9:23:22*/public void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
for(int cellIndex = fromCell; cellIndex <= toCell; cellIndex++ ) {
XWPFTableCell cell = table.getRow(row).getCell(cellIndex);if(cellIndex == fromCell) {
getCellCTTcPr(cell).addNewHMerge().setVal(STMerge.RESTART);} else {
getCellCTTcPr(cell).addNewHMerge().setVal(STMerge.CONTINUE);}}}/*** 跨行合并* @param table* @param col 合并的列* @param fromRow 起始行* @param toRow 终止行* @Description* @Author Huangxiaocong 2018年11月26日 下午9:09:19*/public void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);//第一个合并单元格用重启合并值设置if(rowIndex == fromRow) {
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);} else {
//合并第一个单元格的单元被设置为“继续”cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);}}}/*** @Description: 创建表格,创建后表格至少有1行1列,设置列宽*/public XWPFTable createTable(XWPFDocument xdoc, int rowSize, int cellSize,boolean isSetColWidth, int[] colWidths) {
XWPFTable table = xdoc.createTable(rowSize, cellSize);if (isSetColWidth) {
CTTbl ttbl = table.getCTTbl();CTTblGrid tblGrid = ttbl.addNewTblGrid();for (int j = 0, len = Math.min(cellSize, colWidths.length); j < len; j++) {
CTTblGridCol gridCol = tblGrid.addNewGridCol();gridCol.setW(new BigInteger(String.valueOf(colWidths[j])));}}return table;}/*** @Description: 设置表格总宽度与水平对齐方式*/public void setTableWidthAndHAlign(XWPFTable table, String width,STJc.Enum enumValue) {
CTTblPr tblPr = getTableCTTblPr(table);// 表格宽度CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();if (enumValue != null) {
CTJc cTJc = tblPr.addNewJc();cTJc.setVal(enumValue);}// 设置宽度tblWidth.setW(new BigInteger(width));tblWidth.setType(STTblWidth.DXA);}/*** @Description: 得到Table的CTTblPr,不存在则新建*/public CTTblPr getTableCTTblPr(XWPFTable table) {
CTTbl ttbl = table.getCTTbl();// 表格属性CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();return tblPr;}/*** 设置表格行高* @param infoTable* @param heigth 高度* @param vertical 表格内容的显示方式:居中、靠右...* @Author Huangxiaocong 2018年12月16日 */public void setTableHeight(XWPFTable infoTable, int heigth, STVerticalJc.Enum vertical) {
List<XWPFTableRow> rows = infoTable.getRows();for(XWPFTableRow row : rows) {
CTTrPr trPr = row.getCtRow().addNewTrPr();CTHeight ht = trPr.addNewTrHeight();ht.setVal(BigInteger.valueOf(heigth));List<XWPFTableCell> cells = row.getTableCells();for(XWPFTableCell tableCell : cells ) {
CTTcPr cttcpr = tableCell.getCTTc().addNewTcPr();cttcpr.addNewVAlign().setVal(vertical);}}}
}
实现的效果差不多是这样的,数据会涉及到具体业务所以删除了,凑合看把,哈哈
至此,就酱