Java结合docx4j生成docx文件
程序员文章站
2024-01-30 09:10:30
...
平时项目中经常碰到报表的生成,在此简单描述下使用java结合docx4j技术,生成docx文件的一些基本方法,仅供参考,代码如下:
import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.math.BigInteger; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import javax.imageio.ImageIO; import javax.xml.bind.JAXBException; import org.docx4j.XmlUtils; import org.docx4j.dml.wordprocessingDrawing.Inline; import org.docx4j.jaxb.Context; import org.docx4j.model.structure.SectionWrapper; import org.docx4j.model.table.TblFactory; import org.docx4j.openpackaging.exceptions.InvalidFormatException; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.Part; import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage; import org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart; import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart; import org.docx4j.openpackaging.parts.relationships.Namespaces; import org.docx4j.relationships.Relationship; import org.docx4j.wml.BooleanDefaultTrue; import org.docx4j.wml.CTBorder; import org.docx4j.wml.CTDocProtect; import org.docx4j.wml.CTSettings; import org.docx4j.wml.CTTblLayoutType; import org.docx4j.wml.CTVerticalJc; import org.docx4j.wml.FooterReference; import org.docx4j.wml.Ftr; import org.docx4j.wml.HdrFtrRef; import org.docx4j.wml.Jc; import org.docx4j.wml.JcEnumeration; import org.docx4j.wml.ObjectFactory; import org.docx4j.wml.P; import org.docx4j.wml.PPr; import org.docx4j.wml.RPr; import org.docx4j.wml.STAlgClass; import org.docx4j.wml.STAlgType; import org.docx4j.wml.STBorder; import org.docx4j.wml.STCryptProv; import org.docx4j.wml.STDocProtect; import org.docx4j.wml.STHint; import org.docx4j.wml.STTblLayoutType; import org.docx4j.wml.STVerticalJc; import org.docx4j.wml.SectPr; import org.docx4j.wml.Tbl; import org.docx4j.wml.TblGrid; import org.docx4j.wml.TblGridCol; import org.docx4j.wml.TblPr; import org.docx4j.wml.TblWidth; import org.docx4j.wml.Tc; import org.docx4j.wml.TcPr; import org.docx4j.wml.Tr; import org.docx4j.wml.TrPr; import org.docx4j.wml.SectPr.PgMar; import org.docx4j.wml.TcPrInner.HMerge; import org.docx4j.wml.TcPrInner.TcBorders; import org.docx4j.wml.TcPrInner.VMerge; import org.krysalis.barcode4j.impl.code39.Code39Bean; import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider; /** * 功能描述:报表的工具类 * @author myclover * */ @SuppressWarnings("all") public class Docx4jUtils { /** * 功能描述:创建文档处理包对象 * @return 返回值:返回文档处理包对象 * @throws Exception * @author myclover */ public static WordprocessingMLPackage createWordprocessingMLPackage() throws Exception{ return WordprocessingMLPackage.createPackage(); } /** * 功能描述:获取文档的可用宽度 * @param wordPackage 文档处理包对象 * @return 返回值:返回值文档的可用宽度 * @throws Exception * @author myclover */ private static int getWritableWidth(WordprocessingMLPackage wordPackage)throws Exception{ return wordPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips(); } /** * 功能描述:创建文档表格,上下双边框,左右不封口 * @param rows 行数 * @param cols 列数 * @param widths 每列的宽度 * @return 返回值:返回表格对象 * @author myclover */ public static Tbl createTable(int rows, int cols, int[] widths) { ObjectFactory factory = Context.getWmlObjectFactory(); Tbl tbl = factory.createTbl(); // w:tblPr StringBuffer tblSb = new StringBuffer(); tblSb.append("<w:tblPr ").append(Namespaces.W_NAMESPACE_DECLARATION).append(">"); tblSb.append("<w:tblStyle w:val=\"TableGrid\"/>"); tblSb.append("<w:tblW w:w=\"0\" w:type=\"auto\"/>"); //上边框双线 tblSb.append("<w:tblBorders><w:top w:val=\"double\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); //左边无边框 tblSb.append("<w:left w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>"); //下边框双线 tblSb.append("<w:bottom w:val=\"double\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); //右边无边框 tblSb.append("<w:right w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>"); tblSb.append("</w:tblBorders>"); tblSb.append("<w:tblLook w:val=\"04A0\"/>"); tblSb.append("</w:tblPr>"); TblPr tblPr = null; try { tblPr = (TblPr) XmlUtils.unmarshalString(tblSb.toString()); } catch (JAXBException e) { e.printStackTrace(); } tbl.setTblPr(tblPr); if (tblPr != null) { Jc jc = factory.createJc(); //单元格居中对齐 jc.setVal(JcEnumeration.CENTER); tblPr.setJc(jc); CTTblLayoutType tbll = factory.createCTTblLayoutType(); // 固定列宽 tbll.setType(STTblLayoutType.FIXED); tblPr.setTblLayout(tbll); } // <w:tblGrid><w:gridCol w:w="4788"/> TblGrid tblGrid = factory.createTblGrid(); tbl.setTblGrid(tblGrid); // Add required <w:gridCol w:w="4788"/> for (int i = 1; i <= cols; i++) { TblGridCol gridCol = factory.createTblGridCol(); gridCol.setW(BigInteger.valueOf(widths[i - 1])); tblGrid.getGridCol().add(gridCol); } // Now the rows for (int j = 1; j <= rows; j++) { Tr tr = factory.createTr(); tbl.getContent().add(tr); // The cells for (int i = 1; i <= cols; i++) { Tc tc = factory.createTc(); tr.getContent().add(tc); TcPr tcPr = factory.createTcPr(); tc.setTcPr(tcPr); // <w:tcW w:w="4788" w:type="dxa"/> TblWidth cellWidth = factory.createTblWidth(); tcPr.setTcW(cellWidth); cellWidth.setType("dxa"); cellWidth.setW(BigInteger.valueOf(widths[i - 1])); tc.getContent().add(factory.createP()); } } return tbl; } /** * 功能描述:创建文档表格,全部表格边框都为1 * @param rows 行数 * @param cols 列数 * @param widths 每列的宽度 * @return 返回值:返回表格对象 * @author myclover */ public static Tbl createBorderTable(int rows, int cols, int[] widths) { ObjectFactory factory = Context.getWmlObjectFactory(); Tbl tbl = factory.createTbl(); // w:tblPr StringBuffer tblSb = new StringBuffer(); tblSb.append("<w:tblPr ").append(Namespaces.W_NAMESPACE_DECLARATION).append(">"); tblSb.append("<w:tblStyle w:val=\"TableGrid\"/>"); tblSb.append("<w:tblW w:w=\"0\" w:type=\"auto\"/>"); tblSb.append("<w:tblBorders><w:top w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); tblSb.append("<w:left w:val=\"single\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>"); tblSb.append("<w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); tblSb.append("<w:right w:val=\"single\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>"); tblSb.append("</w:tblBorders>"); tblSb.append("<w:tblLook w:val=\"04A0\"/>"); tblSb.append("</w:tblPr>"); TblPr tblPr = null; try { tblPr = (TblPr) XmlUtils.unmarshalString(tblSb.toString()); } catch (JAXBException e) { e.printStackTrace(); } tbl.setTblPr(tblPr); if (tblPr != null) { Jc jc = factory.createJc(); //单元格居中对齐 jc.setVal(JcEnumeration.CENTER); tblPr.setJc(jc); CTTblLayoutType tbll = factory.createCTTblLayoutType(); // 固定列宽 tbll.setType(STTblLayoutType.FIXED); tblPr.setTblLayout(tbll); } // <w:tblGrid><w:gridCol w:w="4788"/> TblGrid tblGrid = factory.createTblGrid(); tbl.setTblGrid(tblGrid); // Add required <w:gridCol w:w="4788"/> for (int i = 1; i <= cols; i++) { TblGridCol gridCol = factory.createTblGridCol(); gridCol.setW(BigInteger.valueOf(widths[i - 1])); tblGrid.getGridCol().add(gridCol); } // Now the rows for (int j = 1; j <= rows; j++) { Tr tr = factory.createTr(); tbl.getContent().add(tr); // The cells for (int i = 1; i <= cols; i++) { Tc tc = factory.createTc(); tr.getContent().add(tc); TcPr tcPr = factory.createTcPr(); tc.setTcPr(tcPr); // <w:tcW w:w="4788" w:type="dxa"/> TblWidth cellWidth = factory.createTblWidth(); tcPr.setTcW(cellWidth); cellWidth.setType("dxa"); cellWidth.setW(BigInteger.valueOf(widths[i - 1])); tc.getContent().add(factory.createP()); } } return tbl; } /** * 功能描述:创建文档表格,上下双边框,左右不封口 * @param wordPackage 文档处理包对象 * @param rows 表格行数 * @param cols 表格列数 * @param tableWidth 表格的宽度 * @param style 表格的样式 * @param jcEnumerationVal 表格的对齐方式 * @return 返回值:返回表格对象 * @throws Exception * @author myclover */ private static Tbl createTable(WordprocessingMLPackage wordPackage , int rows , int cols , String tableWidth , String style , JcEnumeration jcEnumerationVal)throws Exception{ int writableWidthTwips = getWritableWidth(wordPackage); if(cols == 0){ cols = 1; } int cellWidth = new Double(Math.floor( (writableWidthTwips/cols ))).intValue(); int[] widths = new int[cols]; for(int i = 0 ; i < cols ; i++){ widths[i] = cellWidth; } return createTable(rows, cols, widths); } /** * 功能描述:创建文档表格,表格的默认宽度为:表格样式:dxa,对齐方式:居中 * @param wordPackage 文档处理包对象 * @param rows 表格行数 * @param cols 表格列数 * @param tableWidth 表格宽度 * @return 返回值:返回表格对象 * @throws Exception * @author myclover */ public static Tbl createTable(WordprocessingMLPackage wordPackage , int rows , int cols , String tableWidth) throws Exception{ return createTable(wordPackage, rows, cols, tableWidth , "dxa", JcEnumeration.CENTER); } /** * 功能描述:创建文档表格,表格的默认宽度为:9328,表格样式:dxa,对齐方式:居中 * @param wordPackage 文档处理包对象 * @param rows 表格行数 * @param cols 表格列数 * @return 返回值:返回表格对象 * @throws Exception * @author myclover */ public static Tbl createTable(WordprocessingMLPackage wordPackage , int rows , int cols) throws Exception{ return createTable(wordPackage, rows, cols, "9328", "dxa", JcEnumeration.CENTER); } /** * 功能描述:往文档对象中添加相应的内容 * @param wordPackage 文档处理包对象 * @param info 需要添加的信息 * @param unmarshal 是否有样式,表格对象默认不用 * @throws Exception * @author myclover */ private static void addObject(WordprocessingMLPackage wordPackage , Object info , boolean unmarshal)throws Exception{ if(unmarshal){ wordPackage.getMainDocumentPart().addObject(org.docx4j.XmlUtils.unmarshalString(String.valueOf(info))); }else{ wordPackage.getMainDocumentPart().addObject(info); } } /** * 功能描述:往文档中添加内容 * @param wordPackage 文档处理包对象 * @param info 文档内容 * @throws Exception * @author myclover */ public static void addObject(WordprocessingMLPackage wordPackage , Object info)throws Exception{ addObject(wordPackage, info, true); } /** * 功能描述:往文档中添加表格 * @param wordPackage 文档处理包对象 * @param tbl 表格 * @throws Exception * @author myclover */ public static void addObjectForTbl(WordprocessingMLPackage wordPackage , Tbl tbl)throws Exception{ addObject(wordPackage, tbl, false); } /** * 功能描述:保存文档信息 * @param wordPackage 文档处理包对象 * @param fileName 完整的输出文件名称,包括路径 * @throws Exception * @author myclover */ public static void saveWordPackage(WordprocessingMLPackage wordPackage , String fileName)throws Exception{ saveWordPackage(wordPackage, new File(fileName)); } /** * 功能描述:保存文档信息 * @param wordPackage 文档处理包对象 * @param file 文件 * @throws Exception * @author myclover */ public static void saveWordPackage(WordprocessingMLPackage wordPackage , File file)throws Exception{ wordPackage.save(file); } /** * 功能描述:设置页边距 * @param wordPackage 文档处理包对象 * @param top 上边距 * @param bottom 下边距 * @param left 左边距 * @param right 右边距 * @author myclover */ public static void setMarginSpace(WordprocessingMLPackage wordPackage , String top , String bottom , String left , String right ){ ObjectFactory factory = Context.getWmlObjectFactory(); PgMar pg = factory.createSectPrPgMar(); pg.setTop(new BigInteger(top)); pg.setBottom(new BigInteger(bottom)); pg.setLeft(new BigInteger(left)); pg.setRight(new BigInteger(right)); wordPackage.getDocumentModel().getSections().get(0).getSectPr().setPgMar(pg); } /** * 功能描述:设置页边距,上下边距都为1440,2.54厘米 * @param wordPackage 文档处理包对象 * @param left 左边距 * @param right 右边距 * @author myclover */ public static void setMarginSpace(WordprocessingMLPackage wordPackage , String left , String right ){ setMarginSpace(wordPackage, "1440", "1440", left, right); } /** * 功能描述:设置页边距,上下边距都为1440,2.54厘米,左右边距都为1797,3.17厘米 * @param wordPackage 文档处理包对象 * @author myclover */ public static void setMarginSpace(WordprocessingMLPackage wordPackage){ setMarginSpace(wordPackage, "1440", "1440", "1797", "1797"); } /** * 功能描述:设置字体的样式 * @param fontFamily 字体类型 * @param colorVal 字体颜色 * @param hpsMeasureSize 字号大小 * @param sTHint 字体格式 * @param isBlod 是否加粗 * @return 返回值:返回字体样式对象 * @throws Exception * @author myclover */ private static RPr getRPr(String fontFamily , String colorVal , String hpsMeasureSize , STHint sTHint , boolean isBlod){ ObjectFactory factory = Context.getWmlObjectFactory(); RPr rPr = factory.createRPr(); org.docx4j.wml.RFonts rf = new org.docx4j.wml.RFonts(); rf.setHint(sTHint); rf.setAscii(fontFamily); rf.setHAnsi(fontFamily); rPr.setRFonts(rf); BooleanDefaultTrue bdt = Context.getWmlObjectFactory().createBooleanDefaultTrue(); rPr.setBCs(bdt); if(isBlod){ rPr.setB(bdt); } org.docx4j.wml.Color color = new org.docx4j.wml.Color(); color.setVal(colorVal); rPr.setColor(color); org.docx4j.wml.HpsMeasure sz = new org.docx4j.wml.HpsMeasure(); sz.setVal(new BigInteger(hpsMeasureSize)); rPr.setSz(sz); rPr.setSzCs(sz); return rPr; } /** * 功能描述:设置字体的样式,宋体,黑色,18号 * @param isBlod 是否加粗 * @return 返回值:返回字体样式对象 * @throws Exception * @author myclover */ private static RPr getRPr(boolean isBlod){ return getRPr("宋体", "000000", "18", STHint.EAST_ASIA, isBlod); } /** * 功能描述:设置字体的样式,黑色,18号 * @param fontFamily 字体 * @param isBlod 是否加粗 * @return 返回值:返回字体样式对象 * @throws Exception * @author myclover */ private static RPr getRPr(String fontFamily , boolean isBlod){ return getRPr(fontFamily, "000000", "18", STHint.EAST_ASIA, isBlod); } /** * 功能描述:设置字体的样式,黑色 * @param fontFamily 字体 * @param hpsMeasureSize 字号的大小 * @param isBlod 是否加粗 * @return 返回值:返回字体样式对象 * @throws Exception * @author myclover */ private static RPr getRPr(String fontFamily , String hpsMeasureSize , boolean isBlod){ return getRPr(fontFamily, "000000", hpsMeasureSize, STHint.EAST_ASIA, isBlod); } /** * 功能描述:获取单元格边框样式 * @param type 单元格类型,0表示无边框,2表示双线边框,其他表示单线边框 * @param color 边框颜色 * @param border 边框大小 * @param space 间距 * @return 返回值:返回边框对象 * @author myclover */ private static CTBorder getCTBorder(int type , String color , String border , String space){ CTBorder ctb = new CTBorder(); if(type == 0){ ctb.setVal(STBorder.NIL); }else{ ctb.setColor(color); ctb.setSz(new BigInteger(border)); ctb.setSpace(new BigInteger(space)); if(type == 2){ ctb.setVal(STBorder.DOUBLE); }else{ ctb.setVal(STBorder.SINGLE); } } return ctb; } /** * 功能描述:设置单元格内容对齐方式 * @param p 内容 * @param jcEnumeration 对齐方式 * @author myclover */ public static void setCellContentStyle(P p , JcEnumeration jcEnumeration){ PPr pPr = p.getPPr(); if(pPr == null){ ObjectFactory factory = Context.getWmlObjectFactory(); pPr = factory.createPPr(); } org.docx4j.wml.Jc jc = pPr.getJc(); if(jc == null){ jc = new org.docx4j.wml.Jc(); } jc.setVal(jcEnumeration); pPr.setJc(jc); p.setPPr(pPr); } /** * 功能描述:设置单元格内容对齐方式,居中对齐 * @param p 内容 * @author myclover */ public static void setCellContentStyle(P p){ setCellContentStyle(p, JcEnumeration.CENTER); } /** * 功能描述:填充表格内容 * @param wordPackage 文档处理包对象 * @param tbl 表格对象 * @param dataList 表格数据 * @param titleList 表头数据 * @param isFixedTitle 是否固定表头 * @param tFontFamily 表头字体 * @param tFontSize 表头字体大小 * @param tIsBlod 表头是否加粗 * @param tJcEnumeration 表头对齐方式 * @param fontFamily 表格字体 * @param fontSize 表格字号 * @param isBlod 表格内容是否加粗 * @param jcEnumeration 表格对齐方式 * @author myclover */ private static void fillTableData(WordprocessingMLPackage wordPackage , Tbl tbl , List dataList , List titleList , boolean isFixedTitle,String tFontFamily , String tFontSize , boolean tIsBlod , JcEnumeration tJcEnumeration,String fontFamily , String fontSize , boolean isBlod , JcEnumeration jcEnumeration){ List rowList = tbl.getContent(); //整个表格的行数 int rows = rowList.size(); int tSize = 0; //表头 if(titleList != null && titleList.size() > 0){ tSize = titleList.size(); for(int t = 0 ; t < tSize ; t++){ Object[] tobj = (Object[]) titleList.get(t); Tr tr0 = (Tr) XmlUtils.unwrap(rowList.get(t)); List colList = tr0.getContent(); for(int c = 0 ; c < colList.size() ; c++){ Tc tc0 = (Tc) XmlUtils.unwrap(colList.get(c)); //填充表头数据 fillCellData(tc0, converObjToStr(tobj[c], ""), tFontFamily, tFontSize, tIsBlod, tJcEnumeration); } if(isFixedTitle){ //设置固定表头 fixedTitle(tr0); } } } int colsSize = 1; //表格数据,去掉表头之后的表格数据 for(int r = tSize ; r < rows ; r++){ Tr tr = (Tr) XmlUtils.unwrap(rowList.get(r)); Object[] objs = null; //如果表格内容不为空,则取出相应的数据进行填充 if(dataList != null && (dataList.size() >= (rows - tSize))){ objs = (Object[]) dataList.get(r - tSize); } List colsList = tr.getContent(); //整个表格的列数 colsSize = colsList.size(); for(int i = 0 ; i < colsSize ; i++){ Tc tc = (Tc) XmlUtils.unwrap(colsList.get(i)); //填充表格数据 if(objs != null){ fillCellData(tc, converObjToStr(objs[i], ""), fontFamily, fontSize, isBlod, jcEnumeration); }else{ fillCellData(tc, "", fontFamily, fontSize, isBlod, jcEnumeration); } } } } /** * 功能描述:填充表格内容,固定表头,表头宋体加粗,小五号,表格内容宋体,小五号,表格居中对齐</BR> * 其中表格数据跟表头数据结构要一致,适用于简单的n行m列的普通表格 * @param wordPackage 文档处理包对象 * @param tbl 表格对象 * @param dataList 表格数据 * @param titleList 表头数据,如果不需要表头信息,则只要传入null即可 * @author myclover */ public static void fillTableData(WordprocessingMLPackage wordPackage , Tbl tbl , List dataList , List titleList){ fillTableData(wordPackage, tbl, dataList, titleList, true, "宋体", "18", true, JcEnumeration.CENTER, "宋体", "18", false, JcEnumeration.CENTER); } /** * 功能描述:固定表头 * @param tr 行对象 * @author myclover */ public static void fixedTitle(Tr tr){ ObjectFactory factory = Context.getWmlObjectFactory(); BooleanDefaultTrue bdt = factory.createBooleanDefaultTrue(); //表示固定表头 bdt.setVal(true); TrPr trpr = tr.getTrPr(); if(trpr == null){ trpr = factory.createTrPr(); } trpr.getCnfStyleOrDivIdOrGridBefore().add(factory.createCTTrPrBaseTblHeader(bdt)); tr.setTrPr(trpr); } /** * 功能描述:填充单元格内容 * @param tc 单元格对象 * @param data 内容 * @param fontFamily 字体 * @param fontSize 字号 * @param isBlod 是否加粗 * @param jcEnumeration 对齐方式 * @author myclover */ private static void fillCellData(Tc tc , String data , String fontFamily , String fontSize , boolean isBlod , JcEnumeration jcEnumeration){ ObjectFactory factory = Context.getWmlObjectFactory(); org.docx4j.wml.P p = (P) XmlUtils.unwrap(tc.getContent().get(0)); //设置表格内容的对齐方式 setCellContentStyle(p , jcEnumeration); org.docx4j.wml.Text t = factory.createText(); t.setValue(data); org.docx4j.wml.R run = factory.createR(); //设置表格内容字体样式 run.setRPr(getRPr(fontFamily, fontSize, isBlod)); TcPr tcpr = tc.getTcPr(); if(tcpr == null){ tcpr = factory.createTcPr(); } //设置内容垂直居中 CTVerticalJc valign = factory.createCTVerticalJc(); valign.setVal(STVerticalJc.CENTER); tcpr.setVAlign(valign); run.getContent().add(t); p.getContent().add(run); } /** * 功能描述:填充单元格内容,小五号,宋体,内容居中 * @param tc 单元格对象 * @param data 数据 * @param isBlod 是否加粗 * @author myclover */ public static void fillCellData(Tc tc , String data , boolean isBlod ){ fillCellData(tc, data, "宋体", "18", isBlod, JcEnumeration.CENTER); } /** * 功能描述:获取文字信息 * @param content 文字信息 * @return 返回值:返回值指定样式的信息 * @author myclover */ public static String getContentInfo(String content){ StringBuffer sb = new StringBuffer(); sb.append("<w:p xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" >"); sb.append("<w:pPr><w:spacing w:line=\"360\" w:lineRule=\"auto\"/><w:ind w:firstLineChars=\"200\" w:firstLine=\"480\"/>"); sb.append("<w:rPr><w:rFonts w:asciiTheme=\"minorEastAsia\" w:hAnsiTheme=\"minorEastAsia\"/>"); sb.append("<w:sz w:val=\"24\"/><w:szCs w:val=\"24\"/></w:rPr></w:pPr><w:r w:rsidRPr=\"00792470\"><w:rPr>"); sb.append("<w:rFonts w:asciiTheme=\"minorEastAsia\" w:hAnsiTheme=\"minorEastAsia\" w:hint=\"eastAsia\"/>"); sb.append("<w:sz w:val=\"24\"/><w:szCs w:val=\"24\"/></w:rPr><w:t>"); sb.append(content); sb.append("</w:t></w:r></w:p>"); return sb.toString(); } /** * 功能描述:合并单元格</BR> * 表示合并第startRow(开始行)行中的第startCol(开始列)列到(startCol + colSpan - 1)列 </BR> * 表示合并第startCol(开始列)行中的第startRow(开始行)列到(startRow + rowSpan - 1)行 * @param tc 单元格对象 * @param currentRow 当前行号,传入的是遍历表格时的行索引参数 * @param startRow 开始行 * @param rowSpan 合并的行数,大于1才表示合并 * @param currentCol 当前列号,传入的是遍历表格时的列索引参数 * @param startCol 开始列 * @param colSpan 合并的列数,大于1才表示合并 * @author myclover */ public static void setCellMerge(Tc tc , int currentRow , int startRow , int rowSpan , int currentCol , int startCol , int colSpan){ ObjectFactory factory = Context.getWmlObjectFactory(); TcPr tcpr = tc.getTcPr(); if(tcpr == null){ tcpr = factory.createTcPr(); } //表示合并列 if(colSpan > 1){ //表示从第startRow行开始 if(currentRow == startRow){ //表示从第startRow行的第startCol列开始合并,合并到第startCol + colSpan - 1列 if(currentCol == startCol){ HMerge hm = factory.createTcPrInnerHMerge(); hm.setVal("restart"); tcpr.setHMerge(hm); tc.setTcPr(tcpr); }else if(currentCol > startCol && currentCol <= (startCol + colSpan - 1)){ HMerge hm = factory.createTcPrInnerHMerge(); tcpr.setHMerge(hm); tc.setTcPr(tcpr); } } } //表示合并行 if(rowSpan > 1){ //表示从第startCol列开始 if(currentCol == startCol){ //表示从第startCol列的第startRow行始合并,合并到第startRow + rowSpan - 1行 if(currentRow == startRow){ VMerge vm = factory.createTcPrInnerVMerge(); vm.setVal("restart"); tcpr.setVMerge(vm); tc.setTcPr(tcpr); }else if(currentRow > startRow && currentRow <= (startRow + rowSpan - 1)){ VMerge vm = factory.createTcPrInnerVMerge(); tcpr.setVMerge(vm); tc.setTcPr(tcpr); } } } } /** * 功能描述:合并单元格,相当于跨列的效果</BR> * 表示合并第startRow(开始行)行中的第startCol(开始列)列到(startCol + colSpan - 1)列 </BR> * @param tc 单元格对象 * @param currentRow 当前行号,传入的是遍历表格时的行索引参数 * @param startRow 开始行 * @param currentCol 当前列号,传入的是遍历表格时的列索引参数 * @param startCol 开始列 * @param colSpan 合并的列数,大于1才表示合并 * @author myclover */ public static void setCellHMerge(Tc tc , int currentRow , int startRow , int currentCol , int startCol , int colSpan){ setCellMerge(tc, currentRow, startRow, 1, currentCol, startCol, colSpan); } /** * 功能描述:合并单元格,相当于跨行的效果</BR> * 表示合并第startCol(开始列)行中的第startRow(开始行)列到(startRow + rowSpan - 1)行 * @param tc 单元格对象 * @param currentRow 当前行号,传入的是遍历表格时的行索引参数 * @param startRow 开始行 * @param rowSpan 合并的行数,大于1才表示合并 * @param currentCol 当前列号,传入的是遍历表格时的列索引参数 * @param startCol 开始列 * @author myclover */ public static void setCellVMerage(Tc tc , int currentRow , int startRow , int rowSpan , int currentCol , int startCol){ setCellMerge(tc, currentRow, startRow, rowSpan, currentCol, startCol, 1); } /** * 功能描述:设置文档是否只读,包括内容和样式 * @param wordPackage 文档处理包对象 * @param isReadOnly 是否只读 * @throws Exception * @author myclover */ public static void setReadOnly(WordprocessingMLPackage wordPackage , boolean isReadOnly)throws Exception{ byte[] bt = "".getBytes(); if(isReadOnly){ bt = "123456".getBytes(); } ObjectFactory factory = Context.getWmlObjectFactory(); //创建设置文档对象 DocumentSettingsPart ds = wordPackage.getMainDocumentPart().getDocumentSettingsPart(); if(ds == null){ ds = new DocumentSettingsPart(); } CTSettings cs = ds.getJaxbElement(); if(cs == null){ cs = factory.createCTSettings(); } //创建文档保护对象 CTDocProtect cp = cs.getDocumentProtection(); if(cp == null){ cp = new CTDocProtect(); } //设置加密方式 cp.setCryptProviderType(STCryptProv.RSA_AES); cp.setCryptAlgorithmClass(STAlgClass.HASH); //设置任何用户 cp.setCryptAlgorithmType(STAlgType.TYPE_ANY); cp.setCryptAlgorithmSid(new BigInteger("4")); cp.setCryptSpinCount(new BigInteger("50000")); //只读 if(isReadOnly){ cp.setEdit(STDocProtect.READ_ONLY); cp.setHash(bt); cp.setSalt(bt); //设置内容不可编辑 cp.setEnforcement(true); //设置格式不可编辑 cp.setFormatting(true); }else{ cp.setEdit(STDocProtect.NONE); cp.setHash(null); cp.setSalt(null); //设置内容不可编辑 cp.setEnforcement(false); //设置格式不可编辑 cp.setFormatting(false); } cs.setDocumentProtection(cp); ds.setJaxbElement(cs); //添加到文档主体中 wordPackage.getMainDocumentPart().addTargetPart(ds); } /** * 功能描述:设置文档是否只读,包括内容和样式 * @param fileName 文件 * @param isReadOnly 是否只读 * @return 返回值:设置成功,则返回true,否则返回false * @throws Exception * @author myclover */ public static boolean setReadOnly(String fileName , boolean isReadOnly)throws Exception{ try { File file = new File(fileName); if (!file.exists()) { return false; } //加载需要设置只读的文件 WordprocessingMLPackage wordPackage = WordprocessingMLPackage.load(file); //设置只读 setReadOnly(wordPackage, isReadOnly); //保存文件 saveWordPackage(wordPackage, file); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 功能描述:插入页脚条形码 * @param wordPackage 文档处理包对象 * @param code 条形码编码 * @author myclover */ public static void insertFooterImage(WordprocessingMLPackage wordPackage , String code)throws Exception { try { createFooterReference(wordPackage, createFooterPart(wordPackage, code)); } catch (Exception e) { e.printStackTrace(); throw new Exception("insertFooterImage 插入页脚的条形码失败:" , e); } } /** * 功能描述:创建页脚信息 * @param wordPackage 文档处理包对象 * @param relationship 关联对象 * @throws Exception * @author myclover */ private static void createFooterReference(WordprocessingMLPackage wordPackage,Relationship relationship )throws Exception { org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory(); List<SectionWrapper> sections = wordPackage.getDocumentModel().getSections(); SectPr sectPr = sections.get(sections.size() - 1).getSectPr(); if (sectPr == null ) { sectPr = factory.createSectPr(); wordPackage.getMainDocumentPart().addObject(sectPr); sections.get(sections.size() - 1).setSectPr(sectPr); } FooterReference headerReference = factory.createFooterReference(); headerReference.setId(relationship.getId()); headerReference.setType(HdrFtrRef.DEFAULT); sectPr.getEGHdrFtrReferences().add(headerReference); } /** * 功能描述:创建页脚部分 * @param wordPackage 文档处理包对象 * @param code 条形码编码 * @return * @throws Exception * @author myclover */ private static Relationship createFooterPart(WordprocessingMLPackage wordPackage , String code)throws Exception { FooterPart footerPart = new FooterPart(); footerPart.setPackage(wordPackage); footerPart.setJaxbElement(getFtr(wordPackage , footerPart , code)); return wordPackage.getMainDocumentPart().addTargetPart(footerPart); } /** * 功能描述:获取页脚内容 * @param wordPackage 文档处理包对象 * @param sourcePart 源部分 * @param code 条形码编码 * @return * @throws Exception * @author myclover */ private static Ftr getFtr(WordprocessingMLPackage wordPackage,Part sourcePart , String code) throws Exception { org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory(); Ftr ftr = factory.createFtr(); byte[] bt = generateCode39Barcode(code); ftr.getContent().add(getPImage(wordPackage,sourcePart, bt, "filename", "alttext", 1, 2)); return ftr; } /** * 功能描述:创建页脚条形码图片信息 * @param wordPackage 文档处理包对象 * @param sourcePart 源部分 * @param bytes 字节数组 * @param filenameHint 图片名称 * @param altText 提示信息 * @param id1 id1 * @param id2 id2 * @return * @throws Exception * @author myclover */ private static org.docx4j.wml.P getPImage( WordprocessingMLPackage wordPackage,Part sourcePart,byte[] bytes, String filenameHint, String altText, int id1, int id2) throws Exception { BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordPackage,sourcePart, bytes); Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false); org.docx4j.wml.ObjectFactory factory = new org.docx4j.wml.ObjectFactory(); org.docx4j.wml.P p = factory.createP(); org.docx4j.wml.R run = factory.createR(); p.getContent().add(run); org.docx4j.wml.Drawing drawing = factory.createDrawing(); run.getContent().add(drawing); drawing.getAnchorOrInline().add(inline); PPr pPr = p.getPPr(); if(pPr == null){ pPr = factory.createPPr(); } Jc jc = pPr.getJc(); if(jc == null){ jc = new org.docx4j.wml.Jc(); } //页脚条形码所处位置 jc.setVal(JcEnumeration.RIGHT); pPr.setJc(jc); p.setPPr(pPr); return p; } /** * 功能描述:生成条形码 * @param code 条形码编码 * @return * @throws Exception * @author myclover */ private static byte[] generateCode39Barcode(String code)throws Exception{ Code39Bean bean = new Code39Bean(); //每英寸所打印的点数或线数,用来表示打印机打印分辨率。 final int dpi = 200; bean.setModuleWidth(0.15); bean.setHeight(10); bean.setWideFactor(3); bean.doQuietZone(true); ByteArrayOutputStream out = null; try { out = new ByteArrayOutputStream(); BitmapCanvasProvider canvas = new BitmapCanvasProvider(dpi,BufferedImage.TYPE_BYTE_GRAY, true, 0); bean.generateBarcode(canvas, code); canvas.finish(); BufferedImage barcodeImage = canvas.getBufferedImage(); ImageIO.write(barcodeImage, "jpeg", out); out.flush(); return out.toByteArray(); } catch (Exception e) { e.printStackTrace(); }finally{ if(out != null){ try { out.close(); } catch (Exception e) { e.printStackTrace(); } } } return null; } /** * 功能描述:Object数据转换为String类型 * @param obj * @param defaultStr 如果obj对象为空,则返回的值 * @return * @author myclover */ public static String converObjToStr(Object obj , String defaultStr){ if(obj != null){ return obj.toString(); } return defaultStr; } }
推荐阅读
-
Java结合docx4j生成docx文件
-
通过Java代码生成PDF文件
-
Java根据pdf模板生成荣誉证书PDF文件
-
JasperReport结合JasperReport Studio工具,生成Pdf文件,解决中文不显示问题
-
JAVA --Office文件转换为PPT及PPT文件转换成图片 --支持.docx .xlsx .pptx (使用OpenOffice)
-
java 替换docx文件中的字符串方法实现
-
java将DOC、Docx、PPT、pptx和ODT文档转换为pdf文件
-
Java程序生成exe可执行文件详细教程(图文说明)
-
Java生成压缩文件的实例代码
-
java生成压缩文件示例代码