尊重原创,原文链接
平时项目中经常碰到报表的生成,在此简单描述下使用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;
- }
- }
评论
6 楼
iwwenbo 2015-07-10
虽然看不懂,但觉得很牛叉,专门注册账号赞一个
5 楼
myclover 2013-03-18
wilsonchen 写道
谢谢您的帮助^_^
填充完第一页继续填充第二页,或者使用文档合并功能也可以,这个要怎样实现呢?
如何将第一页的内容填充到第二页呢?合并文档?docx4j可以合并文档?有例子吗?谢谢。
填充完第一页继续填充第二页,或者使用文档合并功能也可以,这个要怎样实现呢?
如何将第一页的内容填充到第二页呢?合并文档?docx4j可以合并文档?有例子吗?谢谢。
填充完第一页数据之后,再调用我上面提到那个强行分页的方法,然后再次填充第一页填充的数据就行了啊
4 楼
wilsonchen 2013-03-17
谢谢您的帮助^_^
填充完第一页继续填充第二页,或者使用文档合并功能也可以,这个要怎样实现呢?
如何将第一页的内容填充到第二页呢?合并文档?docx4j可以合并文档?有例子吗?谢谢。
填充完第一页继续填充第二页,或者使用文档合并功能也可以,这个要怎样实现呢?
如何将第一页的内容填充到第二页呢?合并文档?docx4j可以合并文档?有例子吗?谢谢。
3 楼
myclover 2013-03-16
wilsonchen 写道
楼主,请教您一个问题:
如何利用docx4j copy第一页的数据,然后动态生成第二页,把第一页 的数据copy到第二页中呢?谢谢。
如何利用docx4j copy第一页的数据,然后动态生成第二页,把第一页 的数据copy到第二页中呢?谢谢。
直接使用copy这个我还没用过,不知道api里面有没有提供直接copy的功能,但是你可以研究一下,我觉得要是第一页的内容你都知道了,不防直接循环生成两页,填充完第一页继续填充第二页,或者使用文档合并功能也可以。
强行分页功能:
- /**
- * 功能描述:强行分页功能,调用了此方法会进行强行分页,后面添加的文档内容将会在新页中显示
- * @param wordPackage 文档处理包对象
- * @throws Exception
- * @author myclover
- */
- public static void newPage(WordprocessingMLPackage wordPackage)throws Exception{
- StringBuffer sb = new StringBuffer();
- sb.append("<w:p xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" >");
- sb.append("<w:pPr/><w:r><w:rPr/><w:br w:type=\"page\"/></w:r></w:p>");
- addObject(wordPackage, sb.toString(), true);
- }
相关资源推荐