基础技术调查参考网站:
https://angelozerr.wordpress.com/2012/12/06/how-to-convert-docxodt-to-pdfhtml-with-java/ ---- docx转化为pdf工具的介绍和比较分析
https://github.com/opensagres/xdocreport/wiki/XDocReport103 --XDocReport maven依赖引用介绍
https://stackoverflow.com/questions/38913283/broken-pdf-after-conversion-with-xdocreport ---示例
https://www.programcreek.com/java-api-examples/index.php?api=org.docx4j.openpackaging.packages.WordprocessingMLPackage ---docx4j 示例
https://www.programcreek.com/java-api-examples/index.php?source_dir=wte4j-master/wte4j-core/src/main/java/org/wte4j/impl/word/Docx4JWordTemplate.java
http://www.javafind.net/gate.jsp?q=/library/162/docx4j-3.1.0-javadoc/org/docx4j/openpackaging/parts/WordprocessingML/MainDocumentPart.html --------docx4j api 该网站需要才可访问
www.javafind.net/gate.jsp?q=/library/162/docx4j-3.1.0-javadoc/org/docx4j/convert/out/pdf/viaXSLFO/PdfSettings.html
首先创建一个maven工程
在pom文件中配置依赖
fr.opensagres.xdocreport
fr.opensagres.xdocreport.converter.docx.xwpf
1.0.6
fr.opensagres.xdocreport
org.apache.poi.xwpf.converter.pdf
1.0.6
com.itextpdf
itextpdf
5.4.2
工具类 CreateWordUtils
package cn.sh.cx.ce.maint.biz.pdf.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBElement;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.docx4j.Docx4J;
import org.docx4j.TextUtils;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.finders.RangeFinder;
import org.docx4j.fonts.BestMatchingMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.model.properties.table.tr.TrHeight;
import org.docx4j.model.structure.SectionWrapper;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.utils.BufferUtil;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.Br;
import org.docx4j.wml.CTBookmark;
import org.docx4j.wml.CTBorder;
import org.docx4j.wml.CTHeight;
import org.docx4j.wml.CTShd;
import org.docx4j.wml.CTVerticalJc;
import org.docx4j.wml.Color;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.Drawing;
import org.docx4j.wml.FldChar;
import org.docx4j.wml.FooterReference;
import org.docx4j.wml.Ftr;
import org.docx4j.wml.HdrFtrRef;
import org.docx4j.wml.HpsMeasure;
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.PPrBase.Ind;
import org.docx4j.wml.PPrBase.PBdr;
import org.docx4j.wml.PPrBase.Spacing;
import org.docx4j.wml.R;
import org.docx4j.wml.RFonts;
import org.docx4j.wml.RPr;
import org.docx4j.wml.STBorder;
import org.docx4j.wml.STBrType;
import org.docx4j.wml.STFldCharType;
import org.docx4j.wml.STHint;
import org.docx4j.wml.STLineSpacingRule;
import org.docx4j.wml.STVerticalJc;
import org.docx4j.wml.SectPr;
import org.docx4j.wml.SectPr.PgMar;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.TblBorders;
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.TcPrInner.GridSpan;
import org.docx4j.wml.TcPrInner.HMerge;
import org.docx4j.wml.TcPrInner.TcBorders;
import org.docx4j.wml.TcPrInner.VMerge;
import org.docx4j.wml.Text;
import org.docx4j.wml.TextDirection;
import org.docx4j.wml.Tr;
import org.docx4j.wml.TrPr;
import org.docx4j.wml.U;
import org.docx4j.wml.UnderlineEnumeration;
public class CreateWordUtils {
/**
* 创建word文件创建对象.
*
* @return 创建word对象
* @throws Exception
* @author zhouweiwei
*/
public static WordprocessingMLPackage createWordprocessingMLPackage() throws Exception {
return WordprocessingMLPackage.createPackage();
}
/**
* 保存word文档的方法.
*
* @param wordPackage 创建文档的对象
* @param file 保存路径
* @throws Exception
* @author zhouweiwei
*/
public static void saveWordPackage(WordprocessingMLPackage wordPackage, File file) throws Exception {
wordPackage.save(file);
}
public static void saveWordPackage(WordprocessingMLPackage wordPackage, OutputStream outputStream) throws Exception {
wordPackage.save(outputStream);
}
/**
* 设置段落间的间隙
*
* @param jcEnumeration
* 对齐方式
* @param isSpace
* 是否设置段前段后值
* @param before
* 段前磅数
* @param after
* 段后磅数
* @param beforeLines
* 段前行数
* @param afterLines
* 段后行数
* @param isLine
* 是否设置行距
* @param lineValue
* 行距值
* @param sTLineSpacingRule
* 自动auto 固定exact 最小 atLeast
* @author zhouweiwei
*/
public static void setParagraphSpacing(ObjectFactory factory, P p, JcEnumeration jcEnumeration, boolean isSpace,
String before, String after, String beforeLines, String afterLines, boolean isLine, String lineValue,
STLineSpacingRule sTLineSpacingRule) {
PPr pPr = p.getPPr();
if (pPr == null) {
pPr = factory.createPPr();
}
Jc jc = pPr.getJc();
if (jc == null) {
jc = new Jc();
}
jc.setVal(jcEnumeration);
pPr.setJc(jc);
Spacing spacing = new Spacing();
if (isSpace) {
if (before != null) {
// 段前磅数
spacing.setBefore(new BigInteger(before));
}
if (after != null) {
// 段后磅数
spacing.setAfter(new BigInteger(after));
}
if (beforeLines != null) {
// 段前行数
spacing.setBeforeLines(new BigInteger(beforeLines));
}
if (afterLines != null) {
// 段后行数
spacing.setAfterLines(new BigInteger(afterLines));
}
}
if (isLine) {
if (lineValue != null) {
spacing.setLine(new BigInteger(lineValue));
}
spacing.setLineRule(sTLineSpacingRule);
}
pPr.setSpacing(spacing);
p.setPPr(pPr);
}
/**
* 设置缩进 同时设置为true,则为悬挂缩进
*
* @param factory
* 工厂对象
* @param p
* 段落参数
* @param jcEnumeration
* 字体水平样式
* @param firstLine
* 是否设置首行缩进
* @param firstLineValue
* 设置首行缩进值
* @param hangLine
* 判断是否设悬挂
* @param hangValue
* 设置悬挂值
* @author zhouweiwei
*/
public static void setParagraphInd(ObjectFactory factory, P p, JcEnumeration jcEnumeration, boolean firstLine,
String firstLineValue, boolean hangLine, String hangValue) {
PPr pPr = p.getPPr();
if (pPr == null) {
pPr = factory.createPPr();
}
Jc jc = pPr.getJc();
if (jc == null) {
jc = new Jc();
}
jc.setVal(jcEnumeration);
pPr.setJc(jc);
Ind ind = pPr.getInd();
if (ind == null) {
ind = new Ind();
}
if (firstLine) {
if (firstLineValue != null) {
ind.setFirstLineChars(new BigInteger(firstLineValue));
}
}
if (hangLine) {
if (hangValue != null) {
ind.setHangingChars(new BigInteger(hangValue));
}
}
pPr.setInd(ind);
p.setPPr(pPr);
}
/**
* 创建字体样式
*
* @param isBlod
* 粗体
* @param isUnderLine
* 下划线
* @param isItalic
* 斜体
* @param isStrike
* 删除线
* @author zhouweiwei
*/
public static RPr getRPr(ObjectFactory factory, String fontFamily, String colorVal, String fontSize, STHint sTHint,
boolean isBlod, boolean isUnderLine, boolean isItalic, boolean isStrike) {
RPr rPr = factory.createRPr();
RFonts rf = new RFonts();
rf.setHint(sTHint);
rf.setAscii(fontFamily);
rf.setHAnsi(fontFamily);
rf.setEastAsia(fontFamily);
rPr.setRFonts(rf);
BooleanDefaultTrue bdt = factory.createBooleanDefaultTrue();
rPr.setBCs(bdt);
if (isBlod) {
rPr.setB(bdt);
}
if (isItalic) {
rPr.setI(bdt);
}
if (isStrike) {
rPr.setStrike(bdt);
}
if (isUnderLine) {
U underline = new U();
underline.setVal(UnderlineEnumeration.SINGLE);
rPr.setU(underline);
}
Color color = new Color();
color.setVal(colorVal);
rPr.setColor(color);
HpsMeasure sz = new HpsMeasure();
sz.setVal(new BigInteger(fontSize));
rPr.setSz(sz);
rPr.setSzCs(sz);
return rPr;
}
/**
* 段落中插入文字和图片
*
* @param wordMLPackage
* word文件对象
* @param factory
* 工厂对象
* @param p
* 段落对象
* @param fileName
* 文件名称
* @param content
* 文字内容
* @param bytes
* 字节流对象
* @param jcEnumeration
* 在段落中的位置
* @return 段落对象P
* @throws Exception
* @author zhouweiwei
*
*/
public static P createImageParagraph(WordprocessingMLPackage wordMLPackage, ObjectFactory factory, P p,
String fileName, String content, byte[] bytes, JcEnumeration jcEnumeration) throws Exception {
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);
// /imagePart.setImageInfo(imageInfo);
Inline inline = imagePart.createImageInline(fileName, "这是图片", 0, 1, false);
Text text = factory.createText();
text.setValue(content);
text.setSpace("preserve");
R run = factory.createR();
p.getContent().add(run);
run.getContent().add(text);
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 Jc();
}
jc.setVal(jcEnumeration);
pPr.setJc(jc);
p.setPPr(pPr);
setParagraphSpacing(factory, p, jcEnumeration, true, "0", "0", null, null, true, "240", STLineSpacingRule.AUTO);
return p;
}
/**
* 段落添加图片
*
* @param wordMLPackage
* word文件对象
* @param factory
* 工厂对象
* @param bytes
* 字节流对象
* @param filenameHint
* 文件名称
* @param altText
* 图片说明
* @param id1
* 图片在文档中的在文档中的唯一标识
* @param id2
* 图片在文档中的在文档中其他的唯一标识
* @param isUnderLine
* @param underLineSize
* 是否设置下划线
* @param jcEnumeration
* 在段落中的位置
* @return 段落对象 P
* @throws Exception
* @author zhouweiwei
*/
public static P newImage(WordprocessingMLPackage wordMLPackage, ObjectFactory factory, byte[] bytes,
String filenameHint, String altText, int id1, int id2, boolean isUnderLine, String underLineSize,
JcEnumeration jcEnumeration) throws Exception {
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);
Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false);
P p = factory.createP();
R run = factory.createR();
p.getContent().add(run);
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 Jc();
}
jc.setVal(jcEnumeration);
pPr.setJc(jc);
p.setPPr(pPr);
if (isUnderLine) {
PBdr pBdr = pPr.getPBdr();
if (pBdr == null) {
pBdr = factory.createPPrBasePBdr();
}
CTBorder value = new CTBorder();
value.setVal(STBorder.SINGLE);
value.setColor("000000");
value.setSpace(new BigInteger("0"));
value.setSz(new BigInteger(underLineSize));
pBdr.setBetween(value);
pPr.setPBdr(pBdr);
}
setParagraphSpacing(factory, p, jcEnumeration, true, "0", "0", null, null, true, "240", STLineSpacingRule.AUTO);
return p;
}
/**
* 分页
*
* @param wordMLPackage
* 文档对象
* @param factory
* 工厂对象
* @param sTBrType
* 分页类型
* @author zhouweiwei
*/
public static void addPageBreak(WordprocessingMLPackage wordMLPackage, ObjectFactory factory, STBrType sTBrType) {
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
Br breakObj = new Br();
breakObj.setType(sTBrType);
P paragraph = factory.createP();
paragraph.getContent().add(breakObj);
documentPart.addObject(paragraph);
}
/**
* 得到页面宽度
*
* @param wordPackage
* @return
* @throws Exception
* @author zhouweiwei
*/
public static int getWritableWidth(WordprocessingMLPackage wordPackage) throws Exception {
return wordPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips();
}
/**
* 设置word文档内容里页面的页边距
* 此处设置的为A4
*
* @param wordPackage 文档对象
* @throws Exception 异常
* @author zhouweiwei
*/
public static void setWordPage(WordprocessingMLPackage wordPackage) throws Exception {
PgMar pgSz = new PgMar();
pgSz.setLeft(new BigInteger("851"));
pgSz.setRight(new BigInteger("851"));
pgSz.setTop(new BigInteger("851"));
pgSz.setBottom(new BigInteger("851"));
// 设置页面的宽度
List sections = wordPackage.getDocumentModel().getSections();
SectPr sectPr = sections.get(sections.size() - 1).getSectPr();
sectPr.setPgMar(pgSz);
}
/**
* 设置整列宽度
*
* @param tableWidthPercent
* 表格占页面宽度百分比
* @param widthPercent
* 各列百分比
* @author zhouweiwei
*/
public static void setTableGridCol(WordprocessingMLPackage wordPackage, ObjectFactory factory, Tbl table,
double tableWidthPercent, double[] widthPercent) throws Exception {
int width = getWritableWidth(wordPackage);
int tableWidth = (int) (width * tableWidthPercent / 100);
TblGrid tblGrid = factory.createTblGrid();
for (int i = 0; i < widthPercent.length; i++) {
TblGridCol gridCol = factory.createTblGridCol();
gridCol.setW(BigInteger.valueOf((long) (tableWidth * widthPercent[i] / 100)));
tblGrid.getGridCol().add(gridCol);
}
table.setTblGrid(tblGrid);
TblPr tblPr = table.getTblPr();
if (tblPr == null) {
tblPr = factory.createTblPr();
}
TblWidth tblWidth = new TblWidth();
tblWidth.setType("dxa");// 这一行是必须的,不自己设置宽度默认是auto
tblWidth.setW(new BigInteger(tableWidth + ""));
tblPr.setTblW(tblWidth);
table.setTblPr(tblPr);
}
/**
* 表格水平对齐方式
*
* @param factory
* 工厂对象
* @param table
* 表格对象
* @param jcEnumeration
* 表格水平对齐设置
* @author zhouweiwei
*
*/
public static void setTableAlign(ObjectFactory factory, Tbl table, JcEnumeration jcEnumeration) {
TblPr tablePr = table.getTblPr();
if (tablePr == null) {
tablePr = factory.createTblPr();
}
Jc jc = tablePr.getJc();
if (jc == null) {
jc = new Jc();
}
jc.setVal(jcEnumeration);
tablePr.setJc(jc);
table.setTblPr(tablePr);
}
/**
* 表格增加边框
*
* @param table
* 表格对象
* @param borderSize
* 表格边框宽度
* @author zhouweiwei
*/
public static void addBorders(Tbl table, String borderSize) {
table.setTblPr(new TblPr());
CTBorder border = new CTBorder();
border.setColor("auto");
border.setSz(new BigInteger(borderSize));
border.setSpace(new BigInteger("0"));
border.setVal(STBorder.SINGLE);
TblBorders borders = new TblBorders();
borders.setBottom(border);
borders.setLeft(border);
borders.setRight(border);
borders.setTop(border);
borders.setInsideH(border);
borders.setInsideV(border);
table.getTblPr().setTblBorders(borders);
}
/**
* 设置表格外边框并且去除表格将内部单元格的边框
*
* @param table
* 表格对象
* @param borderSize
* 表格边框的的值
* @param cellSize
* 设置单元格的边框值
* @author zhouweiwei
*/
public static void hideTableCellLineBorders(Tbl table, String borderSize, String cellSize) {
table.setTblPr(new TblPr());
CTBorder tableBorder = new CTBorder();
tableBorder.setColor("auto");
tableBorder.setSz(new BigInteger(borderSize));
tableBorder.setSpace(new BigInteger("0"));
tableBorder.setVal(STBorder.SINGLE);
CTBorder cellBorder = new CTBorder();
cellBorder.setColor("auto");
cellBorder.setSpace(new BigInteger("0"));
cellBorder.setVal(STBorder.NONE);
TblBorders borders = new TblBorders();
borders.setBottom(tableBorder);
borders.setLeft(tableBorder);
borders.setRight(tableBorder);
borders.setTop(tableBorder);
borders.setInsideH(cellBorder);
borders.setInsideV(cellBorder);
table.getTblPr().setTblBorders(borders);
}
/**
* 表格增加边框 可以设置上下左右四个边框样式以及横竖水平线样式
*
* @param table
* 表格对象
* @param topBorder
* 表格上边框样式
* @param bottomBorder
* 表格底边框样式
* @param leftBorder
* 表格左边框样式
* @param rightBorder
* 表格右边框样式
* @param hBorder
* 表格水平方向线的样式
* @param vBorder
* 表格垂直方向线的样式
* @author zhouweiwei
*/
public static void addBorders(Tbl table, CTBorder topBorder, CTBorder bottomBorder, CTBorder leftBorder,
CTBorder rightBorder, CTBorder hBorder, CTBorder vBorder) {
table.setTblPr(new TblPr());
TblBorders borders = new TblBorders();
borders.setBottom(bottomBorder);
borders.setLeft(leftBorder);
borders.setRight(rightBorder);
borders.setTop(bottomBorder);
borders.setInsideH(hBorder);
borders.setInsideV(vBorder);
table.getTblPr().setTblBorders(borders);
}
/**
* 单元格上下左右边框设置
*
* @param tc
* 单元格对象
* @param topBorder
* 边框样式对象
* @param bottomBorder
* 单元格底部边框样式
* @param leftBorder
* 单元格左边框样式
* @param rightBorder
* 设置单元格右边框的样式
* @param tcPr
* 单元格样式对象
* @author zhouweiwei
*/
public static void addCellBorders(Tc tc, CTBorder topBorder, CTBorder bottomBorder, CTBorder leftBorder,
CTBorder rightBorder, TcPr tcPr) {
TcBorders borders = new TcBorders();
borders.setBottom(bottomBorder);
borders.setLeft(leftBorder);
borders.setRight(rightBorder);
borders.setTop(topBorder);
tcPr.setTcBorders(borders);
tc.setTcPr(tcPr);
}
/**
* 设置行的高度
*
* @param factory
* 工程对象
* @param tr
* 行对象
* @param heigth
* 行高度
* @author zhouweiwei
*/
public static void setTableTrHeight(ObjectFactory factory, Tr tr, String heigth) {
TrPr trPr = tr.getTrPr();
if (trPr == null) {
trPr = factory.createTrPr();
}
CTHeight ctHeight = new CTHeight();
ctHeight.setVal(new BigInteger(heigth));
TrHeight trHeight = new TrHeight(ctHeight);
trHeight.set(trPr);
tr.setTrPr(trPr);
}
/**
* 新增单元格
*
* @param factory
* 工程对象
* @param tableRow
* 表格行对象
* @param content
* 填充内容
* @param rpr
* 写入样式对象
* @param jcEnumeration
* 段落位置设置
* @param hasBgColor
* 是否设置颜色
* @param backgroudColor
* 背景颜色
* @author zhouweiwei
*
*/
public static void addTableCell(ObjectFactory factory, Tr tableRow, String content, RPr rpr,
JcEnumeration jcEnumeration, boolean hasBgColor, String backgroudColor) {
Tc tableCell = factory.createTc();
P p = factory.createP();
setParagraphSpacing(factory, p, jcEnumeration, true, "0", "0", null, null, true, "240", STLineSpacingRule.AUTO);
Text t = factory.createText();
t.setValue(content);
R run = factory.createR();
// 设置表格内容字体样式
run.setRPr(rpr);
TcPr tcPr = tableCell.getTcPr();
if (tcPr == null) {
tcPr = factory.createTcPr();
}
// 设置内容垂直方向位置
setCellContentHPosition(factory, tcPr, STVerticalJc.CENTER);
run.getContent().add(t);
p.getContent().add(run);
tableCell.getContent().add(p);
if (hasBgColor) {
CTShd shd = tcPr.getShd();
if (shd == null) {
shd = factory.createCTShd();
}
shd.setColor("auto");
shd.setFill(backgroudColor);
tcPr.setShd(shd);
}
tableCell.setTcPr(tcPr);
tableRow.getContent().add(tableCell);
}
/**
* 创建一般单元格
*
* @param factory
* 工厂对象
* @param tr
* 表格行对象
* @param content
* 单元格填充对象
* @param rpr
* 内容写入对象
* @param jcEnumeration
* 设置内容在单元格的位置
* @param hasBgColor
* 是否设置背景颜色
* @param backgroudColor
* 背景颜色的值
* @param isGridSpan
* 是否设置表格跨列
* @param gridSpanSize
* 表格跨列的大小(跨几列)
* @author zhouweiwei
*/
public static void createNormalCell(ObjectFactory factory, Tr tr, String content, RPr rpr,
JcEnumeration jcEnumeration, boolean hasBgColor, String backgroudColor, boolean isGridSpan,
String gridSpanSize) {
Tc tableCell = factory.createTc();
P p = factory.createP();
setParagraphSpacing(factory, p, jcEnumeration, true, "0", "0", null, null, true, "240", STLineSpacingRule.AUTO);
Text t = factory.createText();
t.setValue(content);
R run = factory.createR();
// 设置表格内容字体样式
run.setRPr(rpr);
TcPr tcPr = tableCell.getTcPr();
if (tcPr == null) {
tcPr = factory.createTcPr();
}
// 设置内容垂直方向位置
setCellContentHPosition(factory, tcPr, STVerticalJc.CENTER);
// 设置单元格是否跨列
if (isGridSpan) {
setCellMerge(tcPr, factory, gridSpanSize);
}
run.getContent().add(t);
p.getContent().add(run);
tableCell.getContent().add(p);
if (hasBgColor) {
CTShd shd = tcPr.getShd();
if (shd == null) {
shd = factory.createCTShd();
}
shd.setColor("auto");
shd.setFill(backgroudColor);
tcPr.setShd(shd);
}
tableCell.setTcPr(tcPr);
tr.getContent().add(tableCell);
}
/**
* 创建含有边框的段落
*
* @param wordMLPackage
* @param t
* @param factory
* @param p
* @param topBorder
* @param bottomBorder
* @param leftBorder
* @param rightBorder
* @author zhouweiwei
*/
public static void createParagraghLine(WordprocessingMLPackage wordMLPackage, MainDocumentPart t,
ObjectFactory factory, P p, CTBorder topBorder, CTBorder bottomBorder, CTBorder leftBorder,
CTBorder rightBorder) {
PPr ppr = new PPr();
PBdr pBdr = new PBdr();
pBdr.setTop(topBorder);
pBdr.setBottom(bottomBorder);
pBdr.setLeft(leftBorder);
pBdr.setRight(rightBorder);
ppr.setPBdr(pBdr);
p.setPPr(ppr);
}
/**
* 设置文字方向 tbRlV 垂直
*
* @param wordPackage
* @param textDirection
* 字体方向值 设置垂直tbRlV
* @return 文字方向TextDirection
* @author zhouweiwei
*/
public static TextDirection setDocTextDirection(WordprocessingMLPackage wordPackage, String textDirection) {
SectPr sectPr = wordPackage.getDocumentModel().getSections().get(0).getSectPr();
TextDirection textDir = sectPr.getTextDirection();
if (StringUtils.isNotBlank(textDirection)) {
if (textDir == null) {
textDir = new TextDirection();
sectPr.setTextDirection(textDir);
}
textDir.setVal(textDirection);
}
return textDir;
}
/**
* 设置表格单元跨列
*
* @param tcPr
* 单元个样式对象
* @param factory
* 对象工厂
* @param gridSpanSize
* 单元格跨行数
* @return 返回单元格的样式对象
* @author zhouweiwei
*/
public static TcPr setCellMerge(TcPr tcPr, ObjectFactory factory, String gridSpanSize) {
GridSpan gr = factory.createTcPrInnerGridSpan();
gr.setVal(new BigInteger(gridSpanSize));
tcPr.setGridSpan(gr);
return tcPr;
}
/**
* 设置表格内容垂直方向的位置
*
* @param factory
* 工厂对象
* @param tcPr
* 表格样式对象
* @param Value
* 表格样式垂直样式设置值
* @return tcPr 返回表格样式
* @author zhouweiwei
*/
public static TcPr setCellContentHPosition(ObjectFactory factory, TcPr tcPr, STVerticalJc Value) {
CTVerticalJc valign = factory.createCTVerticalJc();
valign.setVal(Value);
tcPr.setVAlign(valign);
return tcPr;
}
/**
* 设置单元格边框底部边框显示样式
*
* @param factory
* 工厂对象
* @param tableCell
* 单元格
* @param sTBorder
* 底部边框的线条样式
* @author zhouweiwei
*/
public static void setTableCellBoder(ObjectFactory factory, Tc tableCell, STBorder sTBorder) {
// 给下边框设置虚线
tableCell.setTcPr(factory.createTcPr());
CTBorder cellBorder = factory.createCTBorder();
cellBorder.setColor("auto");
cellBorder.setSpace(new BigInteger("1"));
cellBorder.setVal(sTBorder);
TcBorders tableBorder = new TcBorders();
tableBorder.setBottom(cellBorder);
tableCell.getTcPr().setTcBorders(tableBorder);
}
/**
* 设置单元格边框左部边框显示样式
*
* @param factory
* @param tableCell
* @param sTBorder
*/
public static void setTableCellLeftBoder(ObjectFactory factory, Tc tableCell, STBorder sTBorder) {
// 给下边框设置虚线
tableCell.setTcPr(factory.createTcPr());
CTBorder cellBorder = factory.createCTBorder();
cellBorder.setColor("auto");
cellBorder.setSpace(new BigInteger("0"));
cellBorder.setVal(sTBorder);
TcBorders tableBorder = new TcBorders();
tableBorder.setLeft(cellBorder);
tableCell.getTcPr().setTcBorders(tableBorder);
}
/**
* 跨行和并
*
* @param tbl
* 表格对象
* @param col
* 列对象
* @param fromRow
* 要合并行的开始处
* @param toRow
* 要合并行的结束处
* @author zhouweiwei
*/
public static void mergeCellsVertically(Tbl tbl, int col, int fromRow, int toRow) {
if (col < 0 || fromRow < 0 || toRow < 0) {
return;
}
for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
Tc tc = getTc(tbl, rowIndex, col);
if (tc == null) {
break;
}
TcPr tcPr = getTcPr(tc);
VMerge vMerge = tcPr.getVMerge();
if (vMerge == null) {
vMerge = new VMerge();
tcPr.setVMerge(vMerge);
}
if (rowIndex == fromRow) {
vMerge.setVal("restart");
} else {
vMerge.setVal("continue");
}
}
}
/**
* 得到单元格内容
*
* @param tc
* @return
* @throws Exception
* @author zhouweiwei
*/
public static String getTcContent(Tc tc) throws Exception {
return getElementContent(tc);
}
public static String getElementContent(Object obj) throws Exception {
StringWriter stringWriter = new StringWriter();
TextUtils.extractText(obj, stringWriter);
return stringWriter.toString();
}
/**
* @Description:得到指定位置的单元格
* @author zhouweiwei
*/
public static Tc getTc(Tbl tbl, int row, int cell) {
if (row < 0 || cell < 0) {
return null;
}
List trList = getTblAllTr(tbl);
if (row >= trList.size()) {
return null;
}
List tcList = getTrAllCell(trList.get(row));
if (cell >= tcList.size()) {
return null;
}
return tcList.get(cell);
}
/**
* @Description:得到所有表格
* @author zhouweiwei
*/
public static List getAllTbl(WordprocessingMLPackage wordMLPackage) {
MainDocumentPart mainDocPart = wordMLPackage.getMainDocumentPart();
List objList = getAllElementFromObject(mainDocPart, Tbl.class);
if (objList == null) {
return null;
}
List tblList = new ArrayList();
for (Object obj : objList) {
if (obj instanceof Tbl) {
Tbl tbl = (Tbl) obj;
tblList.add(tbl);
}
}
return tblList;
}
/**
* @Description:得到指定类型的元素
* @author zhouweiwei
*/
public static List getAllElementFromObject(Object obj, Class> toSearch) {
List result = new ArrayList();
if (obj instanceof JAXBElement>)
obj = ((JAXBElement>) obj).getValue();
if (obj.getClass().equals(toSearch))
result.add(obj);
else if (obj instanceof ContentAccessor) {
List> children = ((ContentAccessor) obj).getContent();
for (Object child : children) {
result.addAll(getAllElementFromObject(child, toSearch));
}
}
return result;
}
/**
* @Description: 得到表格所有的行
* @param tbl
* 表格对象
* @author zhouweiwei
*/
public static List getTblAllTr(Tbl tbl) {
List objList = getAllElementFromObject(tbl, Tr.class);
List trList = new ArrayList ();
if (objList == null) {
return trList;
}
for (Object obj : objList) {
if (obj instanceof Tr) {
Tr tr = (Tr) obj;
trList.add(tr);
}
}
return trList;
}
/**
* @Description: 获取所有的单元格
* @author zhouweiwei
*/
public static List getTrAllCell(Tr tr) {
List objList = getAllElementFromObject(tr, Tc.class);
List tcList = new ArrayList();
if (objList == null) {
return tcList;
}
for (Object tcObj : objList) {
if (tcObj instanceof Tc) {
Tc objTc = (Tc) tcObj;
tcList.add(objTc);
}
}
return tcList;
}
public static TcPr getTcPr(Tc tc) {
TcPr tcPr = tc.getTcPr();
if (tcPr == null) {
tcPr = new TcPr();
tc.setTcPr(tcPr);
}
return tcPr;
}
/**
* @Description: 跨列合并
* @author zhouweiwei
*/
public static void mergeCellsHorizontalByGridSpan(Tbl tbl, int row, int fromCell, int toCell) {
if (row < 0 || fromCell < 0 || toCell < 0) {
return;
}
List trList = getTblAllTr(tbl);
if (row > trList.size()) {
return;
}
Tr tr = trList.get(row);
List tcList = getTrAllCell(tr);
for (int cellIndex = Math.min(tcList.size() - 1, toCell); cellIndex >= fromCell; cellIndex--) {
Tc tc = tcList.get(cellIndex);
TcPr tcPr = getTcPr(tc);
if (cellIndex == fromCell) {
GridSpan gridSpan = tcPr.getGridSpan();
if (gridSpan == null) {
gridSpan = new GridSpan();
tcPr.setGridSpan(gridSpan);
}
gridSpan.setVal(BigInteger.valueOf(Math.min(tcList.size() - 1, toCell) - fromCell + 1));
} else {
tr.getContent().remove(cellIndex);
}
}
}
/**
* @Description: 跨列合并
* @author zhouweiwei
*
*/
public static void mergeCellsHorizontal(Tbl tbl, int row, int fromCell, int toCell) {
if (row < 0 || fromCell < 0 || toCell < 0) {
return;
}
List trList = getTblAllTr(tbl);
if (row > trList.size()) {
return;
}
Tr tr = trList.get(row);
List tcList = getTrAllCell(tr);
for (int cellIndex = fromCell, len = Math.min(tcList.size() - 1, toCell); cellIndex <= len; cellIndex++) {
Tc tc = tcList.get(cellIndex);
TcPr tcPr = getTcPr(tc);
HMerge hMerge = tcPr.getHMerge();
if (hMerge == null) {
hMerge = new HMerge();
tcPr.setHMerge(hMerge);
}
if (cellIndex == fromCell) {
hMerge.setVal("restart");
} else {
hMerge.setVal("continue");
}
}
}
/**
* @Description: 添加段落内容
* @author zhouweiwei
*/
public static void appendParaRContent(P p, RPr runProperties, String content) {
if (content != null) {
R run = new R();
p.getContent().add(run);
String[] contentArr = content.split("\n");
Text text = new Text();
text.setSpace("preserve");
text.setValue(contentArr[0]);
run.setRPr(runProperties);
run.getContent().add(text);
for (int i = 1, len = contentArr.length; i < len; i++) {
Br br = new Br();
run.getContent().add(br);// 换行
text = new Text();
text.setSpace("preserve");
text.setValue(contentArr[i]);
run.setRPr(runProperties);
run.getContent().add(text);
}
}
}
/**
* 设置表格之间的间隙
*
* @param factory
* 工厂对象
* @param t
* 页面内容对象
* @param jcEnumeration
* 位置设置
* @param before
* 距离段前的距离或者与之前表格的距离
* @param after
* 距离段后的距离或者与之后表格的距离
* @author zhouweiwei
*/
public static void setTableSpace(ObjectFactory factory, MainDocumentPart t, JcEnumeration jcEnumeration,
String before, String after) {
P para = new P();
RPr contentRpr = getRPr(factory, "宋体", "000000", "18", STHint.EAST_ASIA, false, false, false, false);
setParagraphSpacing(factory, para, jcEnumeration, true, before, after, null, null, true, "240",
STLineSpacingRule.AUTO);
R rp = new R();
Text txtp = new Text();
txtp.setValue("");
rp.getContent().add(txtp);
rp.setRPr(contentRpr);
para.getContent().add(rp);
t.addObject(para);
}
/**
* 创建页脚页数部分
*
* @param wordprocessingMLPackage
* @param t
* @param factory
* @param isUnderLine
* @param underLineSz
* @param jcEnumeration
* @return
* @throws Exception
* @author zhouweiwei
*/
public static Relationship createFooterPageNumPart(WordprocessingMLPackage wordprocessingMLPackage,
MainDocumentPart t, ObjectFactory factory, boolean isUnderLine, String underLineSz,
JcEnumeration jcEnumeration) throws Exception {
FooterPart footerPart = new FooterPart();
footerPart.setPackage(wordprocessingMLPackage);
footerPart.setJaxbElement(createFooterWithPageNr(wordprocessingMLPackage, factory, isUnderLine, underLineSz,
jcEnumeration));
return t.addTargetPart(footerPart);
}
public static Ftr createFooterWithPageNr(WordprocessingMLPackage wordprocessingMLPackage, ObjectFactory factory,
boolean isUnderLine, String underLineSz, JcEnumeration jcEnumeration) throws Exception {
Ftr ftr = factory.createFtr();
P paragraph = factory.createP();
RPr fontRPr = getRPr(factory, "宋体", "000000", "20", STHint.EAST_ASIA, false, false, false, false);
R run = factory.createR();
run.setRPr(fontRPr);
paragraph.getContent().add(run);
addPageTextField(
factory,
paragraph,
"SE-01-FM10,版本号:2 奥的斯电梯(中国)投资有限公司 第一联客户存档 第二联OTIS存档",
fontRPr);
/*
* addPageTextField(factory, paragraph, "第",fontRPr);
* addFieldBegin(factory, paragraph,fontRPr);
* addPageNumberField(factory, paragraph,fontRPr); addFieldEnd(factory,
* paragraph,fontRPr); addPageTextField(factory, paragraph,
* "页",fontRPr);
* addPageTextField(factory, paragraph, " 总共",fontRPr);
* addFieldBegin(factory, paragraph,fontRPr);
* addTotalPageNumberField(factory, paragraph,fontRPr);
* addFieldEnd(factory, paragraph,fontRPr); addPageTextField(factory,
* paragraph, "页",fontRPr);
*/
setParagraphSpacing(factory, paragraph, jcEnumeration, true, "100", "0", null, null, true, "240",
STLineSpacingRule.AUTO);
PPr pPr = paragraph.getPPr();
if (pPr == null) {
pPr = factory.createPPr();
}
Jc jc = pPr.getJc();
if (jc == null) {
jc = new Jc();
}
jc.setVal(jcEnumeration);
pPr.setJc(jc);
if (isUnderLine) {
PBdr pBdr = pPr.getPBdr();
if (pBdr == null) {
pBdr = factory.createPPrBasePBdr();
}
CTBorder value = new CTBorder();
value.setVal(STBorder.SINGLE);
value.setColor("000000");
value.setSpace(new BigInteger("0"));
value.setSz(new BigInteger(underLineSz));
pBdr.setBetween(value);
pPr.setPBdr(pBdr);
paragraph.setPPr(pPr);
}
ftr.getContent().add(paragraph);
if (isUnderLine) {
ftr.getContent().add(
createHeaderAndFooterBlankP(wordprocessingMLPackage, factory, underLineSz, jcEnumeration));
}
return ftr;
}
/**
* 添加页脚内容开始
*
* @param factory
* 工厂对象
* @param paragraph
* 段落对象
* @author zhouweiwei
*/
public static void addFieldBegin(ObjectFactory factory, P paragraph, RPr rPr) {
R run = factory.createR();
FldChar fldchar = factory.createFldChar();
fldchar.setFldCharType(STFldCharType.BEGIN);
run.setRPr(rPr);
run.getContent().add(fldchar);
paragraph.getContent().add(run);
}
/**
* 添加页脚内容结束
*
* @param factory工厂对象
* @param paragraph
* 段落对象
* @author zhouweiwei
*/
public static void addFieldEnd(ObjectFactory factory, P paragraph, RPr rPr) {
FldChar fldcharend = factory.createFldChar();
fldcharend.setFldCharType(STFldCharType.END);
R run3 = factory.createR();
run3.setRPr(rPr);
run3.getContent().add(fldcharend);
paragraph.getContent().add(run3);
}
/**
* 添加页面页数
*
* @param factory
* 工厂对象
* @param paragraph
* 段落对象
*
* @author zhouweiwei
*/
public static void addPageNumberField(ObjectFactory factory, P paragraph, RPr rPr) {
R run = factory.createR();
Text txt = new Text();
txt.setSpace("preserve");
txt.setValue("PAGE \\* MERGEFORMAT ");
run.setRPr(rPr);
run.getContent().add(factory.createRInstrText(txt));
paragraph.getContent().add(run);
}
/**
* 总页数
*
* @param factory
* 工厂对象
* @param paragraph
* 段落对象
* @author zhouweiwei
*/
public static void addTotalPageNumberField(ObjectFactory factory, P paragraph, RPr rPr) {
R run = factory.createR();
Text txt = new Text();
txt.setSpace("preserve");
txt.setValue("NUMPAGES \\* MERGEFORMAT ");
run.setRPr(rPr);
run.getContent().add(factory.createRInstrText(txt));
paragraph.getContent().add(run);
}
/**
* 添加页数的数字的内容
*
* @param factory
* 工厂对象
* @param paragraph
* 段落对象
* @param value
* 页数值
* @author zhouweiwei
*
*/
private static void addPageTextField(ObjectFactory factory, P paragraph, String value, RPr rPr) {
R run = factory.createR();
Text txt = new Text();
txt.setSpace("preserve");
txt.setValue(value);
run.setRPr(rPr);
run.getContent().add(txt);
paragraph.getContent().add(run);
}
/**
* 创建 页眉或者页脚 段落对象
*
* @param wordMLPackage
* 文档对象
* @param factory
* 工厂对象
* @param underLineSz
* 设置段落边框宽度
* @param jcEnumeration
* 段落显示位置
* @return 返回段落对象 P
* @throws Exception
* @author zhouweiwei
*/
public static P createHeaderAndFooterBlankP(WordprocessingMLPackage wordMLPackage, ObjectFactory factory,
String underLineSz, JcEnumeration jcEnumeration) throws Exception {
P p = factory.createP();
R run = factory.createR();
p.getContent().add(run);
PPr pPr = p.getPPr();
if (pPr == null) {
pPr = factory.createPPr();
}
Jc jc = pPr.getJc();
if (jc == null) {
jc = new Jc();
}
jc.setVal(jcEnumeration);
pPr.setJc(jc);
PBdr pBdr = pPr.getPBdr();
if (pBdr == null) {
pBdr = factory.createPPrBasePBdr();
}
CTBorder value = new CTBorder();
value.setVal(STBorder.SINGLE);
value.setColor("000000");
value.setSpace(new BigInteger("0"));
value.setSz(new BigInteger(underLineSz));
pBdr.setBetween(value);
pPr.setPBdr(pBdr);
p.setPPr(pPr);
setParagraphSpacing(factory, p, jcEnumeration, true, "0", "0", null, null, true, "240", STLineSpacingRule.AUTO);
return p;
}
/**
* 创建页脚
*
* @param wordprocessingMLPackage
* word文档对象
* @param t
* 页面内容对象
* @param factory
* 工厂对象
* @param relationship
* @throws InvalidFormatException
* @author zhouweiwei
*/
public static void createFooterReference(WordprocessingMLPackage wordprocessingMLPackage, MainDocumentPart t,
ObjectFactory factory, Relationship relationship) throws InvalidFormatException {
List sections = wordprocessingMLPackage.getDocumentModel().getSections();
SectPr sectPr = sections.get(sections.size() - 1).getSectPr();
// There is always a section wrapper, but it might not contain a sectPr
if (sectPr == null) {
sectPr = factory.createSectPr();
t.addObject(sectPr);
sections.get(sections.size() - 1).setSectPr(sectPr);
}
FooterReference footerReference = factory.createFooterReference();
footerReference.setId(relationship.getId());
footerReference.setType(HdrFtrRef.DEFAULT);
sectPr.getEGHdrFtrReferences().add(footerReference);
}
/**
* 将word转化为pdf
*
* @param inPath
* 要转换的word文件路径
* @param OutPath
* 转化为pdf后的文件路径
*/
public static void wordToPdf(String inPath, String OutPath) {
OutputStream os = null;
try {
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(new File(inPath));
// Mapper fontMapper = new IdentityPlusMapper();
Mapper fontMapper = new BestMatchingMapper();
// fontMapper.getFontMappings().put("华文行楷",
// PhysicalFonts.getPhysicalFonts().get("STXingkai"));
// fontMapper.getFontMappings().put("华文仿宋",
// PhysicalFonts.getPhysicalFonts().get("STFangsong"));
// fontMapper.getFontMappings().put("隶书",
// PhysicalFonts.getPhysicalFonts().get("LiSu"));
// uu.getMsFontsFilenames().put("黑体", value)
fontMapper.getFontMappings().put("黑体", PhysicalFonts.getPhysicalFonts().get("SimHei"));
fontMapper.getFontMappings().put("宋体", PhysicalFonts.getPhysicalFonts().get("SimSun"));
fontMapper.getFontMappings().put("MS Gothic", PhysicalFonts.getPhysicalFonts().get("MS Gothic"));
mlPackage.setFontMapper(fontMapper);
os = new java.io.FileOutputStream(OutPath);
FOSettings foSettings = Docx4J.createFOSettings();
foSettings.setWmlPackage(mlPackage);
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
// Docx4J.toFO(settings, outputStream, flags);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
IOUtils.closeQuietly(os);
}
}
/**
* 将字体设置为黑体 四号 用于文档标题
*
* @param factory
* 工厂对象
* @return 字体样式设置 Rpr
* @author zhouweiwei
*/
public static RPr getTitleFontBoldType(ObjectFactory factory) {
// 黑体四号字体
RPr titleRPr = getRPr(factory, "黑体", "000000", "28", STHint.EAST_ASIA, false, false, false, false);
return titleRPr;
}
/**
* 将字体设置为黑体 五号 用于文档项目项标题
*
* @param factory
* 工厂对象
* @return 字体样式设置 Rpr
* @author zhouweiwei
*/
public static RPr getSeconedTitleFontBoldType(ObjectFactory factory) {
// 黑体五号字体
RPr seconedTitleRPr = getRPr(factory, "黑体", "000000", "21", STHint.EAST_ASIA, false, false, false, false);
return seconedTitleRPr;
}
/**
* 黑体 小五 多用于每一列表格头部标题
*
* @param factory
* 工厂对象 br
* @return 字体样式RPr
* @author zhouweiwei
*/
public static RPr getContentFontBoldType(ObjectFactory factory) {
// 黑体五号字体
RPr rPr = getRPr(factory, "黑体", "000000", "18", STHint.EAST_ASIA, false, false, false, false);
return rPr;
}
/**
* 宋体小五字体不加粗
*
* @param factory
* 工厂对象
* @return 字体样式对象 Rpr
* @author zhouweiwei
*
*/
public static RPr getContentFontSong(ObjectFactory factory) {
// 宋体小五不加粗
RPr contentRPr = getRPr(factory, "宋体", "000000", "18", STHint.EAST_ASIA, false, false, false, false);
return contentRPr;
}
/**
* 宋体小五加粗
*
* @param factory
* 工厂对象
* @return 字体样式对象 Rpr
* @author zhouweiwei
*/
public static RPr getContentFontSongBold(ObjectFactory factory) {
// 宋体小五加粗
RPr contentRPr = getRPr(factory, "宋体", "000000", "18", STHint.EAST_ASIA, true, false, false, false);
return contentRPr;
}
/**
* 宋体8号字体不加粗 用于JHA 表格内容信息
*
* @param factory
* 工厂对象
* @return 字体样式对象 Rpr
* @author zhouweiwei
*/
public static RPr getContentFontSongEigth(ObjectFactory factory) {
// 宋体8号字体
RPr rPr = getRPr(factory, "宋体", "000000", "16", STHint.EAST_ASIA, false, false, false, false);// 宋体
// 8号字体不加粗
return rPr;
}
/**
* 宋体8号字体加粗 用于JHA 表格列的头信息 和行的头的信息
*
* @param factory
* 工厂对象
* @return 字体样式对象 Rpr
* @author zhouweiwei
*/
public static RPr getContentFontSongBoldEigth(ObjectFactory factory) {
// 宋体8号字体加粗
RPr rPr = getRPr(factory, "宋体", "000000", "16", STHint.EAST_ASIA, true, false, false, false);
return rPr;
}
/**
* 设置处理特殊字符的样式 (防止在word转化为pdf时出现乱码 复选框)
*
* @param factory
* 工厂对象
* @return 返回字体样式设置对象
* @author zhouweiwei
*/
public static RPr getSpecialCharacterFont(ObjectFactory factory) {
// 设置特殊字符
RPr rPr = getRPr(factory, "MS Gothic", "000000", "18", STHint.EAST_ASIA, true, false, false, false);
return rPr;
}
/**
* 根据书签获取表格对象 并且不清空对象包含的单元格信息
*
* @param factory 对象工厂
* @param rt 书签游标
* @param marker 目标书签名
* @return 表格对象
* @author zhouweiwei
*/
public static Tbl getTbl(ObjectFactory factory, RangeFinder rt, String marker) {
Tbl tbl = factory.createTbl();
for (CTBookmark bm : rt.getStarts()) {
// 这儿可以对单个书签进行操作,也可以用一个map对所有的书签进行处理
if (bm.getName().equals(marker)) {
// 获取该书签的父级段落
P p = (P) (bm.getParent());
Tc tc = (Tc) (p.getParent());
Tr tr = (Tr) (tc.getParent());
Tbl table = (Tbl) (tr.getParent());
tbl = table;
}
}
return tbl;
}
/**
* 根据书签获取表格对象 并且清空对象包含的单元格信息
*
* @param factory 对象工厂
* @param rt 书签游标
* @param marker 目标书签名
* @return 表格对象
* @author zhouweiwei
*/
public static Tbl getTblNotContent(ObjectFactory factory, RangeFinder rt, String marker) {
Tbl tbl = factory.createTbl();
for (CTBookmark bm : rt.getStarts()) {
// 这儿可以对单个书签进行操作,也可以用一个map对所有的书签进行处理
if (bm.getName().equals(marker)) {
// 获取该书签的父级段落
P p = (P) (bm.getParent());
Tc tc = (Tc) (p.getParent());
Tr tr = (Tr) (tc.getParent());
Tbl table = (Tbl) (tr.getParent());
if (null != table.getContent() && table.getContent().size() > 0) {
table.getContent().clear();
}
tbl = table;
return tbl;
} else {
tbl = null;
}
}
return tbl;
}
/**
* 获取文档中单元格对象
*
* @param factory 对象工厂
* @param rt 书签游标
* @param marker 书签
* @return 单元格对象
*/
public static Tc getTc(ObjectFactory factory, RangeFinder rt, String marker) {
Tc tc = factory.createTc();
for (CTBookmark bm : rt.getStarts()) {
// 这儿可以对单个书签进行操作,也可以用一个map对所有的书签进行处理
if (bm.getName().equals(marker)) {
// 获取该书签的父级段落
P p = (P) (bm.getParent());
Tc cell = (Tc) (p.getParent());
/*
* if(null!=tc .getContent()&& tc .getContent().size()>0 ){
* tc .getContent().clear();
* }
*/
tc = cell;
return tc;
} else {
tc = null;
}
}
return tc;
}
/**
* 获取 段落对象
*
* @param factory 工厂对象
* @param rt 书签游标
* @param marker 书签标记
* @return 返回段落对象
* @author zhouweiwei
*/
public static P getP(ObjectFactory factory, RangeFinder rt, String marker) {
P p = factory.createP();
for (CTBookmark bm : rt.getStarts()) {
// 这儿可以对单个书签进行操作,也可以用一个map对所有的书签进行处理
if (bm.getName().equals(marker)) {
// 获取该书签的父级段落
p = (P) (bm.getParent());
return p;
} else {
p = null;
}
}
return p;
}
/**
* 创建word文档标题.
*
* @author zhouweiwei
* @param t 文档内容对象
* @param factory 工厂对象
* @author zhouweiwei
*/
public static void createWordTempleTitle(MainDocumentPart t, ObjectFactory factory) {
P paragraph = factory.createP();
Text txt = factory.createText();
R run = factory.createR();
setParagraphSpacing(factory, paragraph, JcEnumeration.CENTER, true, "0", "20", null, null, true, "300",
STLineSpacingRule.AUTO);
txt.setValue("${wordTitle}");
run = factory.createR();
run.getContent().add(txt);
run.setRPr(getTitleFontBoldType(factory));
paragraph.getContent().add(run);
t.addObject(paragraph);
}
/**
* 创建内容标题.
*
* @author zhouweiwei
* @param t 文档内容对象
* @param factory 工厂对象
* @param wordContentTitle 标题字符传对象
* @author zhouweiwei
*/
public static void createWordTempleContentTitle(MainDocumentPart t, ObjectFactory factory, String wordContentTitle) {
P paragraph = factory.createP();
setParagraphSpacing(factory, paragraph, JcEnumeration.LEFT, true, "0", "0", null, null, true, "240",
STLineSpacingRule.AUTO);
Text txt = factory.createText();
txt.setValue(wordContentTitle);
// txt.setSpace("preserve");
R run = factory.createR();
run.getContent().add(txt);
run.setRPr(getSeconedTitleFontBoldType(factory));
paragraph.getContent().add(run);
t.addObject(paragraph);
}
/**
* 创建文档logo
*
* @author zhouweiwei
* @param wordMLPackage 文档对象
* @param t 文档内容对象
* @param factory 工厂对象
* @param patch 图片路径
* @throws IOException
* @throws Exception
* @author zhouweiwei
*/
public static void createWordTempleLogoImage(WordprocessingMLPackage wordMLPackage, MainDocumentPart t,
ObjectFactory factory, String patch) throws IOException, Exception {
// 创建表格对象
Tbl table = factory.createTbl();
// 设置表格边框样式
addBorders(table, "0");
// 创建表格样式对象
TblPr tblPr = factory.createTblPr();
// 添加表格缩进
TblWidth tblW = factory.createTblWidth();
tblW.setW(new BigInteger("8629"));
tblW.setType(TblWidth.TYPE_DXA);
tblPr.setTblInd(tblW);
table.setTblPr(tblPr);
// 创建表格行对象
Tr tr = factory.createTr();
// 创建单元格对象
Tc tc = factory.createTc();
// 创建段落对象
P p = factory.createP();
File file = new File(patch);
InputStream is = new FileInputStream(file);
createImageParagraph(wordMLPackage, factory, p, "img_1", "", BufferUtil.getBytesFromInputStream(is),
JcEnumeration.LEFT);
tc.getContent().add(p);
tr.getContent().add(tc);
table.getContent().add(tr);
t.addObject(table);
}
/**
* 加载word模板数据
*
* @param wordTemplatePath word模板路径
* @return 返回word文档对象
* @throws FileNotFoundException
* @throws Docx4JException
* @author zhouweiwei
*/
public static WordprocessingMLPackage getWPackage(String wordTemplatePath) throws FileNotFoundException,
Docx4JException {
return WordprocessingMLPackage.load(new FileInputStream(wordTemplatePath));
}
/**
* 加载word模板流数据
*
* @param is 数据流
* @return 返回
* @throws FileNotFoundException
* @throws Docx4JException
*/
public static WordprocessingMLPackage getWPackage(InputStream is) throws FileNotFoundException, Docx4JException {
return WordprocessingMLPackage.load(is);
}
/**
* word文档转化为pdf对象流
*
* @param wPackage word文档对象
* @param wordTempPath word临时文档路径
* @return 返回pdf数据流
* @throws Exception
* @author zhouweiwei
*/
public static ByteArrayOutputStream getPdfByteArrayOutputStream(String wordTempPath) throws Exception {
// ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
// wPackage.save(pdfOut);
/*
* Mapper fontMapper = new BestMatchingMapper();
* fontMapper.getFontMappings().put("黑体", PhysicalFonts.getPhysicalFonts().get("SimHei"));
* fontMapper.getFontMappings().put("宋体", PhysicalFonts.getPhysicalFonts().get("SimSun"));
* fontMapper.getFontMappings().put("MS Gothic",
* PhysicalFonts.getPhysicalFonts().get("MS Gothic"));
* wPackage.setFontMapper(fontMapper);
* FOSettings foSettings = Docx4J.createFOSettings();
* foSettings.setWmlPackage(wPackage);
* //Docx4J.toPDF(wPackage, pdfOut);
* Docx4J.toFO(foSettings, pdfOut, Docx4J.FLAG_EXPORT_PREFER_XSL);
*/
InputStream in = new FileInputStream(new File(wordTempPath));
// 转换时间测试
/*
* long startpIx=System.currentTimeMillis();;
* IXWPFConverter po= PdfConverter.getInstance();
* System.err.println("Generate pdf with " + (System.currentTimeMillis() - startpcv) +
* "ms-------------------");
* long startpcv=System.currentTimeMillis();
* po.convert(document, pdfOut, options);
* System.err.println("Generate pdf with " + (System.currentTimeMillis() - startpcv) +
* "ms-------------------");
*/
/*
* OutputStream out = new FileOutputStream(new File(
* "E:\\test.pdf"));
* PdfConverter.getInstance().convert(document, out, options);
*/
return getPdfByteArrayOutputStream(in);
}
public static ByteArrayOutputStream getPdfByteArrayOutputStream(InputStream in) throws Exception {
ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
// 从word文档流中获取doc文档内容对象
XWPFDocument document = new XWPFDocument(in);
// 设置PDF编码信息
PdfOptions options = null;
// 进行PDF流对象转化
PdfConverter.getInstance().convert(document, pdfOut, options);
return pdfOut;
}
}
word模板的读取并且 写入数据 (由于下面的实现是从实际库中获取的数据所以你可以参照下面的实现 拿过来直接使用可能你没有对应的数据和实现类对象 来实现你的程序)下面的实现仅供参考
CreateWordTemple
package cn.sh.cx.ce.maint.biz.pdf.service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.docx4j.XmlUtils;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.finders.RangeFinder;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.CTVerticalJc;
import org.docx4j.wml.Document;
import org.docx4j.wml.Drawing;
import org.docx4j.wml.JcEnumeration;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.RPr;
import org.docx4j.wml.STBorder;
import org.docx4j.wml.STHint;
import org.docx4j.wml.STLineSpacingRule;
import org.docx4j.wml.STVerticalJc;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.Tc;
import org.docx4j.wml.TcPr;
import org.docx4j.wml.Text;
import org.docx4j.wml.TextDirection;
import org.docx4j.wml.Tr;
import cn.sh.cx.ce.maint.biz.pdf.model.MaintItemInfo;
import cn.sh.cx.ce.maint.biz.pdf.model.MtrElevBaseInfoPdfData;
import cn.sh.cx.ce.maint.biz.pdf.model.MtrJhaItemDataOut;
import cn.sh.cx.ce.maint.biz.pdf.model.MtrJobEvaluationPdfData;
import cn.sh.cx.ce.maint.biz.pdf.model.MtrMaintFixOut;
import cn.sh.cx.ce.maint.biz.pdf.model.MtrMaintItemPdfData;
import cn.sh.cx.ce.maint.biz.pdf.utils.CreateWordUtils;
/**
* 类 名: CreateWordTemple
* 功能描述: 创建报文模板.
*
* @author zhouweiwei
* @version 1.0
*/
public class CreateWordTemple {
// 1:机房(扶梯上机舱);2:轿顶和井道(扶梯倾斜段);3:坑底(扶梯下机舱);
private static String GENERATORROOM = "1";
private static String CARTOPWELLROAD = "2";
private static String BOTTOM = "3";
// 1:危险内容;2:FPA项目;3:控制方法
private static String DANGEROUSITEMS = "1";
private static String FPAITEMS = "2";
private static String CONTROLMETHOD = "3";
// JHA 为“其他”的 code包含的字符串
private static String OTHER = "_99";
// jHA设置内容=====================================================================================================================
/**
* 创建JHA表格.
*
* @author zhouweiwei
* @param wordMLPackage 文档对象
* @param t 内容对象
* @param factory 工厂对象
* @throws Exception
*/
public void creatJHATable(WordprocessingMLPackage wordMLPackage, MainDocumentPart t, ObjectFactory factory,
RangeFinder rt, List mtrJhaPdfDatas) throws Exception {
Tbl table = CreateWordUtils.getTbl(factory, rt, "JHARFB");
// 取出表格内部线条
// CreateWordUtils.hideTableCellLineBorders(table, "2", "0");
double[] colWidthPercent = new double[] { 7, 15.5, 15.5, 15.5, 15.5, 15.5, 15.5 };// 百分比
CreateWordUtils.setTableGridCol(wordMLPackage, factory, table, 100, colWidthPercent);
if (null != mtrJhaPdfDatas && mtrJhaPdfDatas.size() > 0) {
RPr contentRpr = CreateWordUtils.getContentFontSongEigth(factory);
for (int i = 0; i < 4; i++) {
if (i == 0) {
setJHAItemContent(factory, contentRpr, mtrJhaPdfDatas, GENERATORROOM, "JHARDA", "JHARDB", "JHARFA",
"JHARFB", "JHARMA", "JHARMB", rt);
}
if (i == 1) {
setJHAItemContent(factory, contentRpr, mtrJhaPdfDatas, CARTOPWELLROAD, "JHATDA", "JHATDB",
"JHATFA", "JHATFB", "JHATMA", "JHATMB", rt);
}
if (i == 2) {
setJHAItemContent(factory, contentRpr, mtrJhaPdfDatas, BOTTOM, "JHABDA", "JHABDB", "JHABFA",
"JHABFB", "JHABMA", "JHABMB", rt);
}
}
}
}
/**
* 添加JHA内容项.
*
* @author zhouweiwei
* @param factory 工厂对象
* @param contentTitlePr 表格列头字体样式对象
* @param contentPr 表格内容字体样式
* @param jcEnumeration 内容显示位置
* @param hasBgColor 是否设置字体颜色
* @param backgroudColor 字体颜色
* @param firstTr 行对象
* @param secordTr 行对象
* @param list 内容集合
*/
public void jHATableOtherCellContent(ObjectFactory factory, RPr contentPr, Tc tc, MtrJhaItemDataOut jHAItem) {
P p = factory.createP();
CreateWordUtils.setParagraphSpacing(factory, p, JcEnumeration.LEFT, true, "0", "0", null, null, true, "240",
STLineSpacingRule.AUTO);
R run = factory.createR();
Text txt = factory.createText();
if (jHAItem.getItemCode().endsWith(OTHER)) {
// 含下划线的样式
RPr otherRpr = CreateWordUtils.getRPr(factory, "宋体", "000000", "16", STHint.EAST_ASIA, false, true, false,
false);
txt.setValue("其他:");
run.setRPr(contentPr);
run.getContent().add(txt);
p.getContent().add(run);
// 创建其他项内容信息
R runContent = factory.createR();
Text txtContent = factory.createText();
if (null != jHAItem.getItemOther()) {
runContent.setRPr(otherRpr);
txtContent.setValue(jHAItem.getItemOther());
}
else{
runContent.setRPr(contentPr);
txtContent.setValue("_____");
}
runContent.getContent().add(txtContent);
p.getContent().add(runContent);
} else {
if (jHAItem.getFlag() == 0) {
txt.setValue("□" + jHAItem.getItemName());
run.setRPr(contentPr);
run.getContent().add(txt);
p.getContent().add(run);
} else if (jHAItem.getFlag() == 1) {
txt.setValue("√" + jHAItem.getItemName());
run.setRPr(contentPr);
run.getContent().add(txt);
p.getContent().add(run);
} else {
txt.setValue("");
run.setRPr(contentPr);
run.getContent().add(txt);
p.getContent().add(run);
}
}
tc.getContent().add(p);
}
/**
* 设置JHA列的标题和行的标题
*
* @param factory 工厂对象
* @param coltitle 行的标题
* @param rpr 文本样式对象
* @param jcEnumeration
* @param tr
* @author zhouweiwei
*/
/*
* public void setJHAItemTitle(ObjectFactory factory, String coltitle, RPr rpr, JcEnumeration
* jcEnumeration, Tr tr) {
* // 第一列
* CreateWordUtils.createNormalCell(factory, tr, coltitle, rpr, jcEnumeration, false, null,
* true, "0");
* // 第二列
* CreateWordUtils.createNormalCell(factory, tr, "可能出现下列危险", rpr, jcEnumeration, false, null,
* true, "2");
* // 第三列
* CreateWordUtils.createNormalCell(factory, tr, "可能出现下列FPA项目", rpr, jcEnumeration, false, null,
* true, "2");
* // 第四列
* CreateWordUtils.createNormalCell(factory, tr, "采取的控制方法", rpr, jcEnumeration, false, null,
* true, "2");
* }
*/
/**
* 设置单元格初始化内容
*
* @param factory
* @param tc
* @author zhouweiwei
*/
public void setTcDefaultValue(ObjectFactory factory, Tc tc) {
P p = factory.createP();
CreateWordUtils.setParagraphSpacing(factory, p, JcEnumeration.LEFT, true, "0", "0", null, null, true, "240",
STLineSpacingRule.AUTO);
R run = factory.createR();
Text txt = factory.createText();
txt.setValue("");
run.getContent().add(txt);
p.getContent().add(run);
tc.getContent().add(p);
}
/**
* 给jHA内容框添加下边框
*
* @param factory
* @return 单元格对象
* @author zhouweiwei
*/
public Tc createJHAItemTc(ObjectFactory factory) {
Tc tc = factory.createTc();
// 给下边框设置虚线
CreateWordUtils.setTableCellBoder(factory, tc, STBorder.DOT_DOT_DASH);
setTcDefaultValue(factory, tc);
return tc;
}
/**
* 设置JHA内容向
*
* @param factory 工厂对象
* @param contentPr 文本样式
* @param jcEnumeration 文本显示位置
* @param table 表格
* @param mtrJhaPdfDatas
* @param workType 工作环境类型
*/
public void setJHAItemContent(ObjectFactory factory, RPr contentPr, List mtrJhaPdfDatas,
String workType, String dangeJHAA, String dangeJHAB, String fPAJHAA, String fPAJHAB, String methJHAA,
String methJHAB, RangeFinder rt) {
// 危险项单元格对象
Tc dangeItemTcA = CreateWordUtils.getTc(factory, rt, dangeJHAA);
Tc dangeItemTcB = CreateWordUtils.getTc(factory, rt, dangeJHAB);
// fpa项单元格对象
Tc fPAItemTcA = CreateWordUtils.getTc(factory, rt, fPAJHAA);
Tc fPAItemTcB = CreateWordUtils.getTc(factory, rt, fPAJHAB);
// 方法项单元格对象
Tc methItemTcA = CreateWordUtils.getTc(factory, rt, methJHAA);
Tc methItemTcB = CreateWordUtils.getTc(factory, rt, methJHAB);
boolean colFlg = false;
for (MtrJhaItemDataOut lst : mtrJhaPdfDatas) {
// 设置危险项
if (lst.getWorkAreaType().equals(workType) && lst.getItemType().equals(DANGEROUSITEMS)) {
// 判断将项目放到那一列
if (colFlg) {
jHATableOtherCellContent(factory, contentPr, dangeItemTcB, lst);
colFlg = false;
} else {
jHATableOtherCellContent(factory, contentPr, dangeItemTcA, lst);
colFlg = true;
}
}
// 设置FPA项
if (lst.getWorkAreaType().equals(workType) && lst.getItemType().equals(FPAITEMS)) {
// 判断将项目放到那一列
if (colFlg) {
jHATableOtherCellContent(factory, contentPr, fPAItemTcA, lst);
colFlg = false;
} else {
jHATableOtherCellContent(factory, contentPr, fPAItemTcB, lst);
colFlg = true;
}
}
// 设置方法
if (lst.getWorkAreaType().equals(workType) && lst.getItemType().equals(CONTROLMETHOD)) {
// 判断将项目放到那一列
if (colFlg) {
jHATableOtherCellContent(factory, contentPr, methItemTcA, lst);
colFlg = false;
} else {
jHATableOtherCellContent(factory, contentPr, methItemTcB, lst);
colFlg = true;
}
}
}
}
// ======================================================================================================================================
/**
* 保养项内容设置
*
* @param wordMLPackage
* @param t
* @param factory
* @throws Exception
*/
public void creatMaitItemTable(WordprocessingMLPackage wordMLPackage, MainDocumentPart t, ObjectFactory factory,
RangeFinder rt, List maintItemResult) throws Exception {
RPr contentRpr = CreateWordUtils.getContentFontSong(factory);
Tbl table = CreateWordUtils.getTbl(factory, rt, "maintItem");
CreateWordUtils.addBorders(table, "1");
double[] colWidthPercent = new double[] { 5, 12, 25, 8, 5, 12, 25, 8 };// 百分比
CreateWordUtils.setTableGridCol(wordMLPackage, factory, table, 100, colWidthPercent);
if (null != maintItemResult && maintItemResult.size() > 0) {
// 半年项集合
List halfMothItemLst = getMaintItemTypeLst(maintItemResult, (byte) 1);
// 季度项集合
List quarterItemLst = getMaintItemTypeLst(maintItemResult, (byte) 3);
// 半年项集合
List halfYearItemLst = getMaintItemTypeLst(maintItemResult, (byte) 4);
// 年度项集合
List yearItemLst = getMaintItemTypeLst(maintItemResult, (byte) 5);
// /设置item项行的数量内容
int itemSize = (maintItemResult.size()) / 2;
// 计算取余数
int itemInt = (maintItemResult.size()) % 2;
// 定义表格第一了内容(半月项多出的部分)
int fistItem = 0;
if (halfMothItemLst.size() > itemSize) {
if (itemInt == 0) {
fistItem = halfMothItemLst.size() - itemSize;
} else {
fistItem = halfMothItemLst.size() - (itemSize + 1);
itemSize = itemSize + 1;
}
}
// 半月项多出行的开始下标
int itemCount = halfMothItemLst.size() - fistItem;
// 季度项下标定义
int halfQuarter = 0;
// 半年项下标
int halfYear = 0;
// 年度项下标
int year = 0;
for (int i = 0; i < itemSize; i++) {
Tr itemContentRow = factory.createTr();
if (halfMothItemLst.size() > i) {
// 半月项未折行的部分
if (i > 0) {
setItemTitle(wordMLPackage, factory, null, contentRpr, itemContentRow, false, "");
} else {
setItemTitle(wordMLPackage, factory, halfMothItemLst.get(i), contentRpr, itemContentRow, false,
"");
}
setItemContent(factory, halfMothItemLst.get(i).getMaintItemCode(), contentRpr, itemContentRow);
setItemContent(factory, halfMothItemLst.get(i).getMaintItemName(), contentRpr, itemContentRow);
setItemResult(factory, contentRpr, itemContentRow, halfMothItemLst.get(i));
} else {
setItemContent(factory, null, contentRpr, itemContentRow);
setItemContent(factory, null, contentRpr, itemContentRow);
setItemContent(factory, null, contentRpr, itemContentRow);
setItemContent(factory, null, contentRpr, itemContentRow);
}
// 半月项折行的部分
if (itemCount < halfMothItemLst.size()) {
if (itemCount > halfMothItemLst.size() - fistItem) {
setItemTitle(wordMLPackage, factory, null, contentRpr, itemContentRow, false, "");
} else {
setItemTitle(wordMLPackage, factory, halfMothItemLst.get(itemCount), contentRpr,
itemContentRow, false, "");
}
// setItemTitle(wordMLPackage,factory, halfMothItemLst.get(itemCount),
// contentRpr,
// itemContentRow, false, "");
setItemContent(factory, halfMothItemLst.get(itemCount).getMaintItemCode(), contentRpr,
itemContentRow);
setItemContent(factory, halfMothItemLst.get(itemCount).getMaintItemName(), contentRpr,
itemContentRow);
setItemResult(factory, contentRpr, itemContentRow, halfMothItemLst.get(itemCount));
itemCount++;
} else if (halfQuarter < quarterItemLst.size()) {// 季度项
if (halfQuarter > 0) {
setItemTitle(wordMLPackage, factory, null, contentRpr, itemContentRow, false, "");
} else {
setItemTitle(wordMLPackage, factory, quarterItemLst.get(halfQuarter), contentRpr,
itemContentRow, false, "");
}
setItemContent(factory, quarterItemLst.get(halfQuarter).getMaintItemCode(), contentRpr,
itemContentRow);
setItemContent(factory, quarterItemLst.get(halfQuarter).getMaintItemName(), contentRpr,
itemContentRow);
setItemResult(factory, contentRpr, itemContentRow, quarterItemLst.get(halfQuarter));
halfQuarter++;
} else if (halfYear < halfYearItemLst.size()) {// 半年项
if (halfYear > 0) {
setItemTitle(wordMLPackage, factory, null, contentRpr, itemContentRow, false, "");
} else {
setItemTitle(wordMLPackage, factory, halfYearItemLst.get(halfYear), contentRpr, itemContentRow,
false, "");
}
setItemContent(factory, halfYearItemLst.get(halfYear).getMaintItemCode(), contentRpr,
itemContentRow);
setItemContent(factory, halfYearItemLst.get(halfYear).getMaintItemName(), contentRpr,
itemContentRow);
setItemResult(factory, contentRpr, itemContentRow, halfYearItemLst.get(halfYear));
halfYear++;
} else if (year < yearItemLst.size()) {// 一年项
setItemTitle(wordMLPackage, factory, yearItemLst.get(year), contentRpr, itemContentRow, true, "2");
setItemContentByObj(factory, yearItemLst.get(year), contentRpr, itemContentRow);
setItemResult(factory, contentRpr, itemContentRow, yearItemLst.get(year));
year++;
} else {
setItemContent(factory, null, contentRpr, itemContentRow);
setItemContent(factory, null, contentRpr, itemContentRow);
setItemContent(factory, null, contentRpr, itemContentRow);
setItemContent(factory, null, contentRpr, itemContentRow);
}
table.getContent().add(itemContentRow);
}
// 前一半半年项列标题合并行
CreateWordUtils.mergeCellsVertically(table, 0, 1, itemSize);
if ((halfMothItemLst.size() - fistItem) == halfMothItemLst.size()) {
CreateWordUtils.mergeCellsVertically(table, 4, 1, quarterItemLst.size());
// 半年项标题合并
CreateWordUtils.mergeCellsVertically(table, 4, quarterItemLst.size() + 1, quarterItemLst.size()
+ halfYearItemLst.size());
} else {
// 后部分半月项标题合并
CreateWordUtils.mergeCellsVertically(table, 4, 1, halfMothItemLst.size() - itemSize);
// 季度项标题合并
CreateWordUtils.mergeCellsVertically(table, 4, halfMothItemLst.size() - itemSize + 1,
(halfMothItemLst.size() - itemSize) + quarterItemLst.size());
// 半年项标题合并
CreateWordUtils.mergeCellsVertically(table, 4,
(halfMothItemLst.size() - itemSize) + quarterItemLst.size() + 1,
(halfMothItemLst.size() - itemSize) + quarterItemLst.size() + halfYearItemLst.size());
}
}
}
// 保养项设置内容==============================================================================================================
/**
* 设置保养项内容的方法
*
* @param factory 对象工厂
* @param content 保养项内容
* @param contentRpr 保养项样式
* @param itemContentRow 行对象
* @author zhouweiwei
*/
public void setItemContent(ObjectFactory factory, String content, RPr contentRpr, Tr itemContentRow) {
if (content == null) {
CreateWordUtils.addTableCell(factory, itemContentRow, "", contentRpr, JcEnumeration.LEFT, false, null);
} else {
CreateWordUtils.addTableCell(factory, itemContentRow, content, contentRpr, JcEnumeration.LEFT, false, null);
}
}
/**
* 根据保养项对象信息设置保养项内容方法
* @param factory 对象工厂
* @param obj 保养项对象
* @param contentRpr 样式对象
* @param itemContentRow 表格行对象
*/
public void setItemContentByObj(ObjectFactory factory, MaintItemInfo obj, RPr contentRpr, Tr itemContentRow) {
if (obj == null || obj.getMaintItemName()==null) {
CreateWordUtils.addTableCell(factory, itemContentRow, "", contentRpr, JcEnumeration.LEFT, false, null);
} else {
if(obj.getYearlyFlg()==0){
CreateWordUtils.addTableCell(factory, itemContentRow, obj.getMaintItemName()+"\r\n(建议在年度定期自检时进行)", contentRpr, JcEnumeration.LEFT, false, null);
}
if(obj.getYearlyFlg()==1){
CreateWordUtils.addTableCell(factory, itemContentRow, obj.getMaintItemName(), contentRpr, JcEnumeration.LEFT, false, null);
}
if(obj.getYearlyFlg()==2){
CreateWordUtils.addTableCell(factory, itemContentRow, obj.getMaintItemName(), contentRpr, JcEnumeration.LEFT, false, null);
}
if(obj.getYearlyFlg()==3){
CreateWordUtils.addTableCell(factory, itemContentRow, obj.getMaintItemName(), contentRpr, JcEnumeration.LEFT, false, null);
}
}
}
/**
* 设置保养项类别的标题
*
* @param factory 对象工厂
* @param maintItemCycle 维保项周期 1:半月;3:季度;4:半年;5:年度'
* @param contentRpr 字体样式设置
* @param itemContentRow 行对象
* @param isItemTitle 判断是否要合并列的项
* @param gridSpanSize 合并列的列数
* @param isGridSpan 是否合并列 true是 false 否
* @author zhouweiwei
*/
public void setItemTitle(WordprocessingMLPackage wordPackage, ObjectFactory factory, MaintItemInfo maintItem,
RPr contentRpr, Tr itemContentRow, boolean isGridSpan, String gridSpanSize) {
Tc tableCell = factory.createTc();
P p = factory.createP();
CreateWordUtils.setParagraphSpacing(factory, p, JcEnumeration.LEFT, true, "0", "0", null, null, true, "240",
STLineSpacingRule.AUTO);
Text t = factory.createText();
TcPr tcPr = tableCell.getTcPr();
if (tcPr == null) {
tcPr = factory.createTcPr();
}
// t.setValue(content);
if (null != maintItem) {
if (maintItem.getMaintItemCycle() == 1) {
t.setValue("半月项");
TextDirection textDire = CreateWordUtils.setDocTextDirection(wordPackage, "tbRlV");
tcPr.setTextDirection(textDire);
CTVerticalJc ctv = new CTVerticalJc();
ctv.setVal(STVerticalJc.CENTER);
tcPr.setVAlign(ctv);
} else if (maintItem.getMaintItemCycle() == 3) {
t.setValue("季度项");
TextDirection textDire = CreateWordUtils.setDocTextDirection(wordPackage, "tbRlV");
tcPr.setTextDirection(textDire);
CTVerticalJc ctv = new CTVerticalJc();
ctv.setVal(STVerticalJc.CENTER);
tcPr.setVAlign(ctv);
} else if (maintItem.getMaintItemCycle() == 4) {
t.setValue("半年项");
TextDirection textDire = CreateWordUtils.setDocTextDirection(wordPackage, "tbRlV");
tcPr.setTextDirection(textDire);
CTVerticalJc ctv = new CTVerticalJc();
ctv.setVal(STVerticalJc.CENTER);
tcPr.setVAlign(ctv);
} else if (maintItem.getMaintItemCycle() == 5 && isGridSpan) {
t.setValue(maintItem.getMaintItemCode() + "\r\n(每年一次)");
}
else {
t.setValue("");
}
} else {
t.setValue("");
TextDirection textDire = CreateWordUtils.setDocTextDirection(wordPackage, "tbRlV");
tcPr.setTextDirection(textDire);
CTVerticalJc ctv = new CTVerticalJc();
ctv.setVal(STVerticalJc.CENTER);
tcPr.setVAlign(ctv);
}
R run = factory.createR();
// 设置表格内容字体样式
run.setRPr(contentRpr);
// 设置内容垂直方向位置
CreateWordUtils.setCellContentHPosition(factory, tcPr, STVerticalJc.CENTER);
if (isGridSpan) {
CreateWordUtils.setCellMerge(tcPr, factory, gridSpanSize);
}
run.getContent().add(t);
p.getContent().add(run);
tableCell.getContent().add(p);
tableCell.setTcPr(tcPr);
itemContentRow.getContent().add(tableCell);
}
/**
* 设置保养项结果信息
*
* @param factory 工厂对象
* @param contentRpr 内容字体对象
* @param itemContentRow 行对象
* @param resultState 保养项结果
* @author zhouweiwei
*
*/
public void setItemResult(ObjectFactory factory, RPr contentRpr, Tr itemContentRow, MaintItemInfo in) {
if (null == in.getState()) {
CreateWordUtils.createNormalCell(factory, itemContentRow, "", contentRpr, JcEnumeration.CENTER, false,
null, false, null);
} else if (in.getState() == 0) {
CreateWordUtils.createNormalCell(factory, itemContentRow, "√", contentRpr, JcEnumeration.CENTER, false,
null, false, null);
} else if (in.getState() == 1) {
CreateWordUtils.createNormalCell(factory, itemContentRow, "×", contentRpr, JcEnumeration.CENTER, false,
null, false, null);
} else if (in.getState() == 2) {
CreateWordUtils.createNormalCell(factory, itemContentRow, "○", contentRpr, JcEnumeration.CENTER, false,
null, false, null);
} else if (in.getState() == 3) {
CreateWordUtils.createNormalCell(factory, itemContentRow, "/", contentRpr, JcEnumeration.CENTER, false,
null, false, null);
} else if (in.getState() == -1) {
CreateWordUtils.createNormalCell(factory, itemContentRow, "", contentRpr, JcEnumeration.CENTER, false,
null, false, null);
} else {
CreateWordUtils.createNormalCell(factory, itemContentRow, "", contentRpr, JcEnumeration.CENTER, false,
null, false, null);
}
}
/**
* 根据保养项的类别获取,对数据进行封装
*
* @param maintItemLst 保养项请求集合内容
* @param maintType 保养项类别 '维保项周期 1:半月;3:季度;4:半年;5:年度'
* @return 同一类的保养项
* @author zhouweiwei
*
*/
public List getMaintItemTypeLst(List maintItemLst, Byte maintType) {
List out = new ArrayList();
for (MaintItemInfo item : maintItemLst) {
if (item.getMaintItemCycle() == maintType) {
out.add(item);
}
}
return out;
}
// end======================================================================================================================
/**
* 创建保养项详情信息
*
* @param wordMLPackage 文档对象
* @param factory 对象工厂
* @param t 文档内容对象
* @param rt 书签游标对象
* @throws Exception
* @author zhouweiwei
*/
public void creatMaintItemdetails(WordprocessingMLPackage wordMLPackage, ObjectFactory factory, MainDocumentPart t,
RangeFinder rt, List maintItems) throws Exception {
// 创建表格对象
Tbl table = CreateWordUtils.getTbl(factory, rt, "itemDetail");
CreateWordUtils.addBorders(table, "2");
double[] widthPercent = new double[] { 10, 45, 45 };
CreateWordUtils.setTableGridCol(wordMLPackage, factory, table, 100, widthPercent);
// 创建文本样式显示
RPr contentRpr = CreateWordUtils.getContentFontSong(factory);
if (null != maintItems) {
for (MtrMaintItemPdfData maintItem : maintItems) {
// 创建行对象
Tr tr = factory.createTr();
CreateWordUtils.createNormalCell(factory, tr, maintItem.getMaintItemCode(), contentRpr,
JcEnumeration.LEFT, false, null, false, null);
CreateWordUtils.createNormalCell(factory, tr, maintItem.getMaintItemName(), contentRpr,
JcEnumeration.LEFT, false, null, false, null);
CreateWordUtils.createNormalCell(factory, tr, maintItem.getRequirement(), contentRpr,
JcEnumeration.LEFT, false, null, false, null);
table.getContent().add(tr);
}
}
}
/**
* 设置文档文本信息替换
*
* @param wPackage 文档对象
* @param mainDocumentPart 文档内容对象
* @param factory 对象工厂
* @param wmlDoc 文档word对象
* @param mtrJobEvaluationPdfData
* @throws Exception
* @author zhouweiwei
*/
public void setDataInfo(WordprocessingMLPackage wPackage, MainDocumentPart mainDocumentPart, ObjectFactory factory,
Document wmlDoc, MtrJobEvaluationPdfData mtrJobEvaluationPdfData, RangeFinder rt,
MtrElevBaseInfoPdfData baseInfo, MtrMaintFixOut mtrMaintFixResult) throws Exception {
// 客户签名
if (null != mtrJobEvaluationPdfData && null != mtrJobEvaluationPdfData.getSign()) {
setCustSign(factory, wPackage, rt, mtrJobEvaluationPdfData.getSign());
}
// 将word内容部分转化为String
String xml = XmlUtils.marshaltoString(wmlDoc, true, true);
HashMap map = new HashMap();
// 设置工作满意度
SetSatisfaction(map, mtrJobEvaluationPdfData);
// 客户姓名
if (null != mtrJobEvaluationPdfData && null != mtrJobEvaluationPdfData.getCustomerName()) {
map.put("custName", mtrJobEvaluationPdfData.getCustomerName());
} else {
map.put("custName", "");
}
// 签字日期
if (null != mtrJobEvaluationPdfData && null != mtrJobEvaluationPdfData.getSignTime()) {
map.put("signTime", StringUtils.substring(mtrJobEvaluationPdfData.getSignTime(), 0, 10));
} else {
map.put("signTime", "");
}
// 技师名
if (null != mtrJobEvaluationPdfData && null != mtrJobEvaluationPdfData.getEmplNameCh()) {
map.put("techName", mtrJobEvaluationPdfData.getEmplNameCh());
} else {
map.put("techName", "");
}
// 文档名 和 基本信息替换
if (null != baseInfo) {
map.put("wordTitle", StringUtils.defaultIfEmpty(baseInfo.getMaintSequence(), ""));
map.put("branchName", StringUtils.defaultIfEmpty(baseInfo.getBrandName(), ""));
map.put("customerCompany", StringUtils.defaultIfEmpty(baseInfo.getCustomerCompany(), ""));
map.put("elevCode", StringUtils.defaultIfEmpty(baseInfo.getElevCode(), ""));
map.put("elevModel", StringUtils.defaultIfEmpty(baseInfo.getElevModel(), ""));
map.put("contCode", StringUtils.defaultIfEmpty(baseInfo.getContCode(), ""));
} else {
map.put("wordTitle", "");
map.put("branchName", "");
map.put("customerCompany", "");
map.put("elevCode", "");
map.put("elevModel", "");
map.put("contCode", "");
}
// 本次工作中发现的问题及需要客户处理的事项 技师备注内容
if (null != mtrMaintFixResult && null != mtrMaintFixResult.getTechComment()) {
map.put("techComment", mtrMaintFixResult.getTechComment());
} else {
map.put("techComment", "");
}
// 本次工作中发现的问题及需要客户处理的事项 改造标记内容
setIsReplaceOrReform(map, mtrMaintFixResult);
// 将map中的数据替换模本里面的标签内容
Object po = XmlUtils.unmarshallFromTemplate(xml, map);
mainDocumentPart.setJaxbElement((Document) po);
wPackage.addTargetPart(mainDocumentPart);
}
/**
* 设置工作满意度
*
* @param map
* @param mtrJobEvaluationPdfData
*/
public void SetSatisfaction(HashMap map, MtrJobEvaluationPdfData mtrJobEvaluationPdfData) {
if (null != mtrJobEvaluationPdfData) {
if (null != mtrJobEvaluationPdfData.getAttitude()) {
// 工作评价信息设置 服务态度
if (mtrJobEvaluationPdfData.getAttitude() == 1) {
map.put("veryPl", "√");
map.put("pl", "□");
map.put("notPl", "□");
}
// 工作评价信息设置 服务态度
if (mtrJobEvaluationPdfData.getAttitude() == 2) {
map.put("veryPl", "□");
map.put("pl", "√");
map.put("notPl", "□");
}
// 工作评价信息设置 服务态度
if (mtrJobEvaluationPdfData.getAttitude() == 3) {
map.put("veryPl", "□");
map.put("pl", "□");
map.put("notPl", "√");
}
} else {
map.put("veryPl", "□");
map.put("pl", "□");
map.put("notPl", "□");
}
if (null != mtrJobEvaluationPdfData.getQuality()) {
// 工作评价信息设置 服务态度
if (mtrJobEvaluationPdfData.getQuality() == 1) {
map.put("veryPl2", "√");
map.put("pl2", "□");
map.put("notPl2", "□");
}
// 工作评价信息设置 服务态度
if (mtrJobEvaluationPdfData.getQuality() == 2) {
map.put("veryPl2", "□");
map.put("pl2", "√");
map.put("notPl2", "□");
}
// 工作评价信息设置 服务态度
if (mtrJobEvaluationPdfData.getQuality() == 3) {
map.put("veryPl2", "□");
map.put("pl2", "□");
map.put("notPl2", "√");
}
} else {
map.put("veryPl2", "□");
map.put("pl2", "□");
map.put("notPl2", "□");
}
if (null != mtrJobEvaluationPdfData.getQuestion()) {
map.put("pro", mtrJobEvaluationPdfData.getQuestion());
} else {
map.put("pro", "");
}
} else {
map.put("veryPl", "□");
map.put("pl", "□");
map.put("notPl", "□");
map.put("veryPl2", "□");
map.put("pl2", "□");
map.put("notPl2", "□");
map.put("pro", "");
}
}
/**
* 设置客户签名
*
* @param factory 工厂对象
* @param wPackage 文档包对象
* @param rt 书签对象
* @throws IOException
* @throws Exception
* @author zhouweiwei
*/
public void setCustSign(ObjectFactory factory, WordprocessingMLPackage wPackage, RangeFinder rt, byte[] custStream)
throws IOException, Exception {
// 填充图片内容
// InputStream is = new FileInputStream(new File("E:\\12.png"));
// BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wPackage,
// BufferUtil.getBytesFromInputStream(is));
// 对图片二进制流进行封装和绘图
BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wPackage, custStream);
// Inline inline = imagePart.createImageInline("E:\\12.png", "这是图片", 1, 2, false);
Inline inline = imagePart.createImageInline(null, "客户签名", 1, 0, 1021737, 1021737, false);
Drawing drawing = factory.createDrawing();
drawing.getAnchorOrInline().add(inline);
RPr contentRpr = CreateWordUtils.getRPr(factory, "宋体", "000000", "18", STHint.EAST_ASIA, false, false, false,
false);
Tc tc = CreateWordUtils.getTc(factory, rt, "custSign");
if (null != tc) {
tc.getContent().clear();
P para = factory.createP();
CreateWordUtils.setParagraphSpacing(factory, para, JcEnumeration.LEFT, true, "0", "0", null, null, true,
"240", STLineSpacingRule.AUTO);
R r = factory.createR();
/*
* Text txt = factory.createText();
* txt.setValue("测试使用");
*/
r.getContent().add(drawing);
r.setRPr(contentRpr);
para.getContent().add(r);
tc.getContent().add(para);
}
}
/**
* 描述:换件,改造设置(本次工作中发现的问题及需要客户处理的事项 改造和替换内容)
*
* @param map 替换内容map
* @param mtrMaintFixResult 换件,改造 对象
* @author zhouweiwei
*/
public void setIsReplaceOrReform(HashMap map, MtrMaintFixOut mtrMaintFixResult) {
if (null != mtrMaintFixResult) {
if (null != mtrMaintFixResult.getFixFlg()) {
if (mtrMaintFixResult.getFixFlg() == 0) {
map.put("Tb1", "□");
} else if (mtrMaintFixResult.getFixFlg() == 1) {
map.put("Tb1", "√");
}
} else {
map.put("Tb1", "□");
}
if (null != mtrMaintFixResult.getReconstrFlg()) {
if (mtrMaintFixResult.getReconstrFlg() == 0) {
map.put("Tb2", "□");
}
if (mtrMaintFixResult.getReconstrFlg() == 1) {
map.put("Tb2", "√");
}
} else {
map.put("Tb2", "□");
}
} else {
map.put("Tb1", "□");
map.put("Tb2", "□");
}
}
}
下面的方法是调用 CreateWordTemple类和CreateWordUtils 并且返回流给客户端
public byte[] pdfReptDataStream(MaintainingReportPdfData in) throws Exception {
long start = System.currentTimeMillis();
// 创建word文档的类
CreateWordTemple ws = new CreateWordTemple();
// 获取文档模板
InputStream wordTemplatePathIs = this.getClass().getResourceAsStream("maintRpWordTemplate.docx");
// 载入模板文件
WordprocessingMLPackage wPackage = CreateWordUtils.getWPackage(wordTemplatePathIs);
// 提取正文
MainDocumentPart mainDocumentPart = wPackage.getMainDocumentPart();
ObjectFactory factory = Context.getWmlObjectFactory();
Document wmlDoc = (Document) mainDocumentPart.getContents();
Body body = wmlDoc.getBody();
// 提取正文中所有段落
List paragraphs = body.getContent();
// 提取书签并创建书签的游标
RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");
new TraversalUtil(paragraphs, rt);
// jha项
ws.creatJHATable(wPackage, mainDocumentPart, factory, rt, in.getMtrJhaPdfDatas());
// 保养项目结果
ws.creatMaitItemTable(wPackage, mainDocumentPart, factory, rt, in.getMaintItemResult());
// 维保项目及要求pdf数据
ws.creatMaintItemdetails(wPackage, factory, mainDocumentPart, rt, in.getMaintItems());
// 模板数据替换
ws.setDataInfo(wPackage, mainDocumentPart, factory, wmlDoc, in.getMtrJobEvaluationPdfData(), rt,
in.getMtrElevBaseInfoPdfData(), in.getMtrMaintFixResult());
// 设置文档页面的内容的里页边距的大小(A4样式)
CreateWordUtils.setWordPage(wPackage);
// 定义生成的word保存为输出流的形式
ByteArrayOutputStream outStreamTempl = new ByteArrayOutputStream();
CreateWordUtils.saveWordPackage(wPackage, outStreamTempl);
// 将输出流转化为输入流
InputStream inStreamTempl = new ByteArrayInputStream(outStreamTempl.toByteArray());
// 将word流转化为pdf流
ByteArrayOutputStream pdfOut = CreateWordUtils.getPdfByteArrayOutputStream(inStreamTempl);
// 将对象流转化为二进制流对象
byte[] out = pdfOut.toByteArray();
pdfOut.flush();
// 关闭流对象
pdfOut.close();
System.err.println("Generate pdf with " + (System.currentTimeMillis() - start) + "ms");
return out;
// pdf流转成PDF文件测试
/*
* InputStream inpp = new ByteArrayInputStream(out);
* OutputStream fos = new FileOutputStream(new File(
* "E:\\HelloWorld11.pdf"));
* byte[] b = new byte[1024];
* int nRead = 0;
* while ((nRead = inpp.read(b)) != -1) {
* fos.write(b, 0, nRead);
* }
* fos.flush();
* fos.close();
* inpp.close();
*/
}
你可能感兴趣的:(报表工具)
帆软报表嵌入python程序_FineReport 报表工具的使用与集成
weixin_39531374
帆软报表嵌入python程序
一直以来,报表功能的开发都是应用系统开发的重点难点。近年来,一些基于Excel的报表工具的涌现使得报表开发变得越来越简便,极大地减轻了系统开发人员的负担。本文将介绍一款优秀的报表工具———java报表软件FineReport的基本使用及其与系统工程的集成方法。一、FineReport介绍FineReportjava报表软件是一款纯Java编写的企业级Web报表软件工具。它能够全面支持主流的B/S架
在尝试了市面上90%的报表工具后,终于找到了这款免费万能的报表工具!
枝上棉蛮
数据可视化 数字孪生 免费报表工具 报表制作 数据分析 数据可视化 数据处理 数字孪生
经常有朋友私信问我有“哪个报表工具好用易上手?”或者是“有哪些适合绝大多数普通职场人的万能报表工具?”等问题。在这里我总结出大家在报表选择时最在意的三个要点。一、挑选报表工具的重点1)低门槛上手难度:理想中的报表工具应当具备高度的用户友好性,即“开箱即用”的便捷性。这意味着,即便是对技术不甚精通的职场人士,也能迅速上手,无需投入大量时间学习复杂操作或深究高级功能。毕竟,大多数人追求的是快速、有效地
『开源资讯』JimuReport积木报表 v1.6.6 版本发布—免费报表工具
报表工具报表数据可视化数据分析
项目介绍一款免费的数据可视化报表,含报表和大屏设计,像搭建积木一样在线设计报表!功能涵盖,数据报表、打印设计、图表报表、大屏设计等!Web版报表设计器,类似于excel操作风格,通过拖拽完成报表设计。秉承“简单、易用、专业”的产品理念,极大的降低报表开发难度、缩短开发周期、节省成本、解决各类报表难题。领先的企业级Web报件,采用纯Web在线技术,专注于解决企业报表快速制作难题。当前版本:v1.6.
报表工具有没有sql植入风险?如何规避?
昵称叫啥捏
报表检测到sql植入风险,一般是报表工具提供了通用查询的功能,也就意味着sql(sql类数据集)是可以通过参数动态拼接的。如where子句:Select…fromTwhere${w}正常使用下w可以“status=1”、“1=1”等灵活的条件,但同时存在很大的安全隐患。比如w为“1=0UNIONselect…fromuser”时,user表数据就完全泄露了。解决这个问题大概两种方式:1、写成很牛X
SAP BW/4HANA学习笔记1
偶是不器
学习 数据仓库 数据挖掘 数据库 数据分析
1.MasterDataBW/4HANABW/4HANA简介BW/4HANA的前身是SAPBW(BusinessWarehouse),本质是一种数据仓库解决方案。数据仓库解决方案:1.云端仓库;2.SAPHANAforSQL,偏个人SQL定制;3.SAPBW/4HANA;BW/4HANA的三层结构。SAPBW/4HANA,SAPS/4HANA提供报表工具,单一般不使用embeddedAnalyti
SAP Query如何使用
JamesG0204
ABAP sap abap
Query是SAP的一项简单报表工具,对于开发人员和功能顾问来说,可以在较短的时间不通过开发代码来实现报表功能,并且可以将Query使用权限授予一个或多个用户。創建1個Query共有三步。創建UserGroup,并分配用戶給用戶組。(T-code:SQ03);創建InfoSet。(T-code:SQ02);InfoSet可以直接讀取表,也可以讀取多個關聯的表,還可以引用LDB。創建完InfoSet
软考笔记--数据仓库技术
赤露水
软考 笔记 数据仓库
数据仓库是一个面向主题的,集成的,相对稳定的、反映历史变化的数据集合,用于支持管理决策。数据源是数据仓库系统的基础,是整个系统的数据源泉。OLAP(联机分析处理)服务器对分析需要的数据进行有效集成,按多维模型予以组织,以便进行多角度、多层次的分析,并发现趋势。前端工具主要包括各种报表工具,查询工具,数据分析工具和数据挖掘工具,以及各种基于数据仓库或数据集市的应用开发工具。其中数据分析工具主要针对O
哪款报表工具更适合行业软件开发商?
心宇gxy
行业软件开发商(以下简称开发商)是我国最常见的软件公司了,其本身具备较强的技术能力,而且每年都会承接很多项目,在选择报表工具时的关注点与技术能力不强(大部分)、且在较长时间内只选购一次产品的行业终端用户有很大不同。开发商关心报表工具,以及一切工具性产品,主要都是两条:1.可用性。功能再多再强,如果在自己的体系下不可用,那没有意义。2.低成本。在可用的提前下,要选择成本尽量低的方案。这里的成本是指整
报表工具对比选型系列—多样性数据源支持度
心宇gxy
本次仍然评测这几款主流的报表工具:润乾报表、帆软报表、Smartbi、永洪BI、亿信。之前在多源关联分片报表中验证了各个报表工具的多数据源关联功能,这些产品都能支持多数据源,但对不同类型数据源的支持程度并不一样。目前常用的关系型数据库基本上都提供jdbc接口,所有报表工具都支持,这里就不做详细说明,下面主要看下几种数据源的支持情况:1、文件数据源,如Excel、txt、csv等。2、webserv
质量管理QMS系统实施的好处是什么?
万界星空科技
质量管理 QMS 万界星空科技 运维 大数据 科技 制造 5G
每个企业都在做质量提升的工作,很多质量人也在为“提升”二字所奔波。然而,如何做好质量管理?在这之前必须要了解质量管理的核心是什么?对于产品制造商而言,质量管理一直是让其头痛的一个问题,质量问题究其原因还是由人为的。所以,质量管理的核心就是预防人犯错。1、制造执行过程透明化通过QMS系统实时采集如工序产量、工单在制品转移状况、检验、产品不良故障等详细生产过程数据,并提供汇总分析报表工具,为企业不同管
fineReport网络报表工具使用总结
以我清欢
从上周五开始接触finereport报表工具开始到现在,已经熟悉大部分的操作,现在准备记录下几个简单和常用的操作。1.序号的添加无论是组内序号还是普通的序号只需在放置序号的单元格中插入公式seq(),接着再为这个单元格设置左父格即可。2.页内合计与总计总计:和excel相同,为sum(D2),表式D2单元格内扩展出来的值的总和。页内合计:sum({D2}),表示对当前页的D2单元格扩展出来的值求和
biee的书 oracle_ORACLE BIEE技术手册及示例.doc
善良是多余的
biee的书 oracle
ORACLEBIEE技术手册及示例ORACLEBIEE技术手册及示例BIEE基本架构体系需要注意的是:BIEE是分析工具,不是专业报表工具,同时也不能完全复制出EXCLE中所体现出来的特殊表和图的效果。企业商务智能标准架构信息的一般模型OracleBI体系组成下面的图例反映了OracleBI的体系组成以及各组成部分的关联。Clients(客户端):提供访问信息的权限和服务OracleBIAnswe
5款强大的开源报表工具!
King斌
图片最近发现几款不错的开源报表,还提供源码,现在给大家分享一下,希望能带来帮助!关注我是程序汪1、项目名称:积木报表项目简介:积木报表,免费的企业级WEB报表工具。专注于“专业、易用、优质”的报表设计器和大屏设计器。支持打印设计、数据报表、图形报表、大屏设计器,重点是免费的。项目地址:https://github.com/zhangdaiscott/JimuReport/issues/new体验地
从只用Excel做报表,到Excel报表工具真香,他经历了什么?
一帆简书
9102年了,很多人,乃至于很多企业做报表都还在用Excel,埋头苦干一天整出下面这个玩意:你的辛苦领导都看在眼里,但是这做的实在是太差了,一点都不能反映数字之间的关系,于是领导回复了你一句:回去重做.....其实,经常和报表打交道的人都知道,用Excel制作报表是一件非常麻烦的事情,不仅因为用Excel做报表步骤繁多,同时业务需求变化也会让报表改来改去,回工成本太大。尤其是对于财务、IT来说,用
实现报表的可控缓存
小黄鸭呀
【摘要】使用缓存可以提升报表性能是不争的事实,一般高端报表工具都会提供报表缓存功能,可将整个报表计算结果缓存在文件系统中,以便用户下次访问相同参数的报表时可以快速读取缓存结果进行展现。但有些情况下报表开发人员还希望对缓存的内容进行更准确和灵活的控制,比如缓存的不是整个报表结果而是其中一部分、缓存内容可被其它报表或程序复用,以及对不同的缓存结果设置不同的超时时间,从而应对数据量和实时性方面的不同情况
Visual Studio 2022 使用RDLC报表分享
hecgaoyuan
visual studio 大数据 ide
最近项目里需要报表选型工作,需要免费使用,这个让我来选材一下,经过一番查找,收费的就不能用了,免费里报表工具能够完全支撑落地的也很少,最后发现RDLC给我们带来了曙光,一开始担心由于在网上看到都是NetFarmework环境下进行说明,另外这个东东在VS2005的时候就已经出现并且使用了,在ASP.NETWINFROMWPF上面使用,担心在Netcore以上版本还能支持吗,于是动手验证得出结论,微
使用FastReport报表工具生成标签打印文档
伍华聪_开发框架
在我们实际开发报表的时候,我们需要按一定的业务规则组织好报表的模板设计,让报表尽可能的贴近实际的需求,在之前的随笔中《使用FastReport报表工具生成报表PDF文档》介绍了FastReport生成常规报表的处理,本篇随笔回顾常规报表的处理效果,并介绍基于FastReport生成标签纸打印需要的报表格式。1、常规报表的处理我们一般处理报表的时候,大多数情况碰到的是明细报表,或者有主从表这种样式的
开源项目_大模型应用_Chat2DB
xieyan0811
大模型 ChatGPT 数据库
1基本信息项目地址:https://github.com/chat2db/Chat2DBStar:10.7K2功能Chat2DB是一个智能且多功能的SQL客户端和报表工具,适用于各种数据库。对于那些平时会用到数据库,但又不是数据库专家的程序员来说,Chat2DB可以说是一种福音。通过查看README中的视频,可以了解到Chat2DB的核心功能和用法。其功能可分为三个主要部分:支持Chat功能,可以
创意交融:集成自定义报表和仪表盘设计器,实现图标替换
葡萄城技术团队
服务器 运维
前言在现代数据分析领域,随着对报表和数据分析的需求不断增长,市场上涌现了许多嵌入式报表工具。这些工具能够与企业现有的OA、ERP、MES、CRM等应用系统深度集成,实现对业务数据的自助式分析。然而,在实际应用中,不同的系统往往具有独特的界面模式和风格,这就要求嵌入式报表插件的UI界面需要与系统本身的UI风格相匹配。因此,在本文中,小编将以葡萄城公司的嵌入式BI工具——Wyn商业智能软件为例,介绍如
属性还是servlet参数,报表工具功能点控制方式探讨2022-11-23
拓跋杉月
在皕杰报表工具规划的新版本中,拟将带有查询表单的报表是否根据缺省参数值自动查询的设置放到报表查询表单属性里去设置,原来版本中这个功能点是通过在url中后跟servlet参数autoquery=ture来实现的。在报表工具中,某一个功能点的实现的方式不是唯一的,可以放在属性中实现,也可以放在servlet参数中实现的。那么这两种实现方式各有什么优缺点呢?属性中实现的好处就是易操作,可以在设计报表时选
新年福利|这款价值数万的报表工具永久免费了
思迈特Smartbi
Smartbi 思迈特软件 电子表格软件 数据分析
随着数据资产的价值逐渐凸显,越来越多的企业会希望采用报表工具来处理数据分析,了解业务经营状况,从而辅助经营决策。不过,企业在选型报表工具的时候经常会遇到以下几个问题:各个报表工具有很多功能和特性,但是不一定能满足企业的实际使用需求;习惯使用Excel、代码开发或者类Excel报表工具,很难适应新的报表工具,使用效率低;预算缩减,急需一款价格亲民、功能强大、易用且安全可靠的报表工具。能够满足企业用户
Java报表是什么?盘点2024最实用的四款Java报表!
VeryReport-非常报表软件
java 开发语言
Java报表工具在Java环境下发挥着重要的作用,它们通过提供可视化操作界面,支持通用jdbc数据库,并可以输出多种格式报表,帮助用户更好地处理和分析数据。这些工具应用广泛,例如在数据展示、数据统计和分析、数据监控以及报告生成等方面。一、Java报表推荐1.VeryReportVeryReport报表软件设计器界面在众多Java报表工具中,有几款高效便捷的工具值得推荐。首先是VeryReport,
一文详解报表工具和BI工具的区别
VeryReport-非常报表软件
信息可视化
在接触BI商业智能时,许多人会对其与报表的区别感到困惑。实际上,报表和BI商业智能在发展历程、功能和目的等方面都有所不同。下面,我们将从三个角度为大家详细解读报表工具及BI工具的区别。添加图片注释,不超过140字(可选)首先,让我们回顾一下报表和BI商业智能的发展历程。早期,报表工具主要用于生成纸质报表,随着计算机技术的发展,电子表格如Excel开始普及,使得用户能够更加灵活地创建数据类报表。随着
最热门的5款Java报表工具
VeryReport-非常报表软件
java 开发语言
目前,Java是最流行的开发语言之一,Java除了简单之外,还具有生态丰富,最重要的是跨平台,天生具有跨平台优势,可轻松部署到Windows、Linux、Unix、MacOS等操作系统。Java报表工具又分为C/S结构和B/S结构。C/S(Client/Server):客户端-服务器结构。C/S主要特点是交互性强、具有安全的存取模式、网络通信量低、响应速度快。但是,由于每次更新都需要每台客户端都需
试用了所有热门的报表工具,终于找到这款好用的报表工具,太赞了
VeryReport-非常报表软件
信息可视化
经常有朋友向我咨询,有没有哪个报表工具既简单易上手,又适合绝大多数普通职场人使用。经过我的一番研究,我发现大家在选择报表工具时,主要关注以下3点:1.简单易上手:大家希望报表工具的学习门槛低,无需花费过多精力就能上手操作。毕竟,对于大多数职场人来说,可能一辈子只会用到报表工具的10%功能,如果为了那90%的功能而需要付出额外的学习成本,实在有些得不偿失。2.万能适用:大家希望报表工具的适用范围广泛
MetaBase指南-Mac下的注册&安装
啥都会点的狐狸
Metabase的定位就是简单的BI报表工具,支持MySQL和其他主流的数据库。可以直接通过”Question“的SQL直接提取数据,然后生成柱状图或者饼图。如果你经有了清洗好的数据仓库,那么用这个是最快速的办法生成数据仪表板,而不用再去用什么BI工具。Metabase的最新版支持了Docker和Amazon云安装,不过我没有相应的环境,要是有阿里云的一键安装倒是可以试试。对于我这种一个人数据工程
【Flink SQL API体验数据湖格式之paimon】
以茉萱
flink sql 大数据
前言随着大数据技术的普及,数据仓库的部署方式也在发生着改变,之前在部署数据仓库项目时,首先想到的是选择国外哪家公司的产品,比如:数据存储会从Oracle、SqlServer中或者Mysql中选择,ETL工具会从Informatica、DataStage或者Kettle中选择,BI报表工具会从IBMcognos、SapBo或者帆软中选择,基本上使用的产品组合都类似,但随着数据量的激增,之前的部署方式
报表工具价格谁最优?
心宇gxy
我们在实际项目中选择报表工具时,除了关心功能是否能够满足需求,也会非常关心产品价格,即报表工具在项目中的应用成本,包括购买工具的花费和投入的人力成本,也就是我们经常提到的“性价比”。面对琳琅满目的报表工具以及厂商包装出来各种“高大上”的功能,想要“选对”,而不“选贵”有时并不容易。那么,如何选择适合的报表工具既能满足项目需要,又能有效控制项目成本,达到高性价比呢?这里我们来谈谈如何根据不同的项目情
【开源项目推荐】-支持GPT的智能数据库客户端与报表工具——Chat2DB
大数据流动
开源 gpt 数据库
2023年是人工智能爆火的一年,ChatGPT为首的一系列的大模型的出现,让生成式人工智能彻底火了一把。但有人会说,GPT对于我们数据开发来说并没有什么作用啊?今天为大家推荐的开源项目,就是GPT在数据领域的一个优秀实践项目。让我们一起来看看吧~Chat2DB是一个集成了ChatGPT功能的数据库SQL客户端和报表工具,支持windows、mac本地安装,也支持服务器端部署,web网页访问。和传统
从Excel到智能化:智能报表的演进与未来发展趋势 | 文末免费领取数据分析鼠标垫
excelbi
摘要:本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。报表的迭代历程报表工具的诞生与计算机技术的出现和信息技术的进步密不可分。下图是报表工具的演进历程:注:上图是小编根据报表的演进历史整理而成1、手工报表:在古代,人们使用纸笔手工记录和整理数据,并制作简单的报表。这些报表通常是手写的,包含基本的数字和文字。2、机械
强大的销售团队背后 竟然是大数据分析的身影
蓝儿唯美
数据分析
Mark Roberge是HubSpot的首席财务官,在招聘销售职位时使用了大量数据分析。但是科技并没有挤走直觉。
大家都知道数理学家实际上已经渗透到了各行各业。这些热衷数据的人们通过处理数据理解商业流程的各个方面,以重组弱点,增强优势。
Mark Roberge是美国HubSpot公司的首席财务官,HubSpot公司在构架集客营销现象方面出过一份力——因此他也是一位数理学家。他使用数据分析
Haproxy+Keepalived高可用双机单活
bylijinnan
负载均衡 keepalived haproxy 高可用
我们的应用MyApp不支持集群,但要求双机单活(两台机器:master和slave):
1.正常情况下,只有master启动MyApp并提供服务
2.当master发生故障时,slave自动启动本机的MyApp,同时虚拟IP漂移至slave,保持对外提供服务的IP和端口不变
F5据说也能满足上面的需求,但F5的通常用法都是双机双活,单活的话还没研究过
服务器资源
10.7
eclipse编辑器中文乱码问题解决
0624chenhong
eclipse乱码
使用Eclipse编辑文件经常出现中文乱码或者文件中有中文不能保存的问题,Eclipse提供了灵活的设置文件编码格式的选项,我们可以通过设置编码 格式解决乱码问题。在Eclipse可以从几个层面设置编码格式:Workspace、Project、Content Type、File
本文以Eclipse 3.3(英文)为例加以说明:
1. 设置Workspace的编码格式:
Windows-&g
基础篇--resources资源
不懂事的小屁孩
android
最近一直在做java开发,偶尔敲点android代码,突然发现有些基础给忘记了,今天用半天时间温顾一下resources的资源。
String.xml 字符串资源 涉及国际化问题
http://www.2cto.com/kf/201302/190394.html
string-array
接上篇补上window平台自动上传证书文件的批处理问卷
酷的飞上天空
window
@echo off
: host=服务器证书域名或ip,需要和部署时服务器的域名或ip一致 ou=公司名称, o=公司名称
set host=localhost
set ou=localhost
set o=localhost
set password=123456
set validity=3650
set salias=s
企业物联网大潮涌动:如何做好准备?
蓝儿唯美
企业
物联网的可能性也许是无限的。要找出架构师可以做好准备的领域然后利用日益连接的世界。
尽管物联网(IoT)还很新,企业架构师现在也应该为一个连接更加紧密的未来做好计划,而不是跟上闸门被打开后的集成挑战。“问题不在于物联网正在进入哪些领域,而是哪些地方物联网没有在企业推进,” Gartner研究总监Mike Walker说。
Gartner预测到2020年物联网设备安装量将达260亿,这些设备在全
spring学习——数据库(mybatis持久化框架配置)
a-john
mybatis
Spring提供了一组数据访问框架,集成了多种数据访问技术。无论是JDBC,iBATIS(mybatis)还是Hibernate,Spring都能够帮助消除持久化代码中单调枯燥的数据访问逻辑。可以依赖Spring来处理底层的数据访问。
mybatis是一种Spring持久化框架,要使用mybatis,就要做好相应的配置:
1,配置数据源。有很多数据源可以选择,如:DBCP,JDBC,aliba
Java静态代理、动态代理实例
aijuans
Java静态代理
采用Java代理模式,代理类通过调用委托类对象的方法,来提供特定的服务。委托类需要实现一个业务接口,代理类返回委托类的实例接口对象。
按照代理类的创建时期,可以分为:静态代理和动态代理。
所谓静态代理: 指程序员创建好代理类,编译时直接生成代理类的字节码文件。
所谓动态代理: 在程序运行时,通过反射机制动态生成代理类。
一、静态代理类实例:
1、Serivce.ja
Struts1与Struts2的12点区别
asia007
Struts1与Struts2
1) 在Action实现类方面的对比:Struts 1要求Action类继承一个抽象基类;Struts 1的一个具体问题是使用抽象类编程而不是接口。Struts 2 Action类可以实现一个Action接口,也可以实现其他接口,使可选和定制的服务成为可能。Struts 2提供一个ActionSupport基类去实现常用的接口。即使Action接口不是必须实现的,只有一个包含execute方法的P
初学者要多看看帮助文档 不要用js来写Jquery的代码
百合不是茶
jquery js
解析json数据的时候需要将解析的数据写到文本框中, 出现了用js来写Jquery代码的问题;
1, JQuery的赋值 有问题
代码如下: data.username 表示的是: 网易
$("#use
经理怎么和员工搞好关系和信任
bijian1013
团队 项目管理 管理
产品经理应该有坚实的专业基础,这里的基础包括产品方向和产品策略的把握,包括设计,也包括对技术的理解和见识,对运营和市场的敏感,以及良好的沟通和协作能力。换言之,既然是产品经理,整个产品的方方面面都应该能摸得出门道。这也不懂那也不懂,如何让人信服?如何让自己懂?就是不断学习,不仅仅从书本中,更从平时和各种角色的沟通
如何为rich:tree不同类型节点设置右键菜单
sunjing
contextMenu tree Richfaces
组合使用target和targetSelector就可以啦,如下: <rich:tree id="ruleTree" value="#{treeAction.ruleTree}" var="node" nodeType="#{node.type}"
selectionChangeListener=&qu
【Redis二】Redis2.8.17搭建主从复制环境
bit1129
redis
开始使用Redis2.8.17
Redis第一篇在Redis2.4.5上搭建主从复制环境,对它的主从复制的工作机制,真正的惊呆了。不知道Redis2.8.17的主从复制机制是怎样的,Redis到了2.4.5这个版本,主从复制还做成那样,Impossible is nothing! 本篇把主从复制环境再搭一遍看看效果,这次在Unbuntu上用官方支持的版本。 Ubuntu上安装Red
JSONObject转换JSON--将Date转换为指定格式
白糖_
JSONObject
项目中,经常会用JSONObject插件将JavaBean或List<JavaBean>转换为JSON格式的字符串,而JavaBean的属性有时候会有java.util.Date这个类型的时间对象,这时JSONObject默认会将Date属性转换成这样的格式:
{"nanos":0,"time":-27076233600000,
JavaScript语言精粹读书笔记
braveCS
JavaScript
【经典用法】:
//①定义新方法
Function .prototype.method=function(name, func){
this.prototype[name]=func;
return this;
}
//②给Object增加一个create方法,这个方法创建一个使用原对
编程之美-找符合条件的整数 用字符串来表示大整数避免溢出
bylijinnan
编程之美
import java.util.LinkedList;
public class FindInteger {
/**
* 编程之美 找符合条件的整数 用字符串来表示大整数避免溢出
* 题目:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0
*
* 假设当前正在搜索由0,1组成的K位十进制数
读书笔记
chengxuyuancsdn
读书笔记
1、Struts访问资源
2、把静态参数传递给一个动作
3、<result>type属性
4、s:iterator、s:if c:forEach
5、StringBuilder和StringBuffer
6、spring配置拦截器
1、访问资源
(1)通过ServletActionContext对象和实现ServletContextAware,ServletReque
[通讯与电力]光网城市建设的一些问题
comsci
问题
信号防护的问题,前面已经说过了,这里要说光网交换机与市电保障的关系
我们过去用的ADSL线路,因为是电话线,在小区和街道电力中断的情况下,只要在家里用笔记本电脑+蓄电池,连接ADSL,同样可以上网........
 
oracle 空间RESUMABLE
daizj
oracle 空间不足 RESUMABLE 错误挂起
空间RESUMABLE操作 转
Oracle从9i开始引入这个功能,当出现空间不足等相关的错误时,Oracle可以不是马上返回错误信息,并回滚当前的操作,而是将操作挂起,直到挂起时间超过RESUMABLE TIMEOUT,或者空间不足的错误被解决。
这一篇简单介绍空间RESUMABLE的例子。
第一次碰到这个特性是在一次安装9i数据库的过程中,在利用D
重构第一次写的线程池
dieslrae
线程池 python
最近没有什么学习欲望,修改之前的线程池的计划一直搁置,这几天比较闲,还是做了一次重构,由之前的2个类拆分为现在的4个类.
1、首先是工作线程类:TaskThread,此类为一个工作线程,用于完成一个工作任务,提供等待(wait),继续(proceed),绑定任务(bindTask)等方法
#!/usr/bin/env python
# -*- coding:utf8 -*-
C语言学习六指针
dcj3sjt126com
c
初识指针,简单示例程序:
/*
指针就是地址,地址就是指针
地址就是内存单元的编号
指针变量是存放地址的变量
指针和指针变量是两个不同的概念
但是要注意: 通常我们叙述时会把指针变量简称为指针,实际它们含义并不一样
*/
# include <stdio.h>
int main(void)
{
int * p; // p是变量的名字, int *
yii2 beforeSave afterSave beforeDelete
dcj3sjt126com
delete
public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
if($insert) {
//这里是新增数据
} else {
//这里是更新数据
}
}
 
timertask
shuizhaosi888
timertask
java.util.Timer timer = new java.util.Timer(true);
// true 说明这个timer以daemon方式运行(优先级低,
// 程序结束timer也自动结束),注意,javax.swing
// 包中也有一个Timer类,如果import中用到swing包,
// 要注意名字的冲突。
TimerTask task = new
Spring Security(13)——session管理
234390216
session Spring Security 攻击保护 超时
session管理
目录
1.1 检测session超时
1.2 concurrency-control
1.3 session 固定攻击保护
 
公司项目NODEJS实践0.3[ mongo / session ...]
逐行分析JS源代码
mongodb session nodejs
http://www.upopen.cn
一、前言
书接上回,我们搭建了WEB服务端路由、模板等功能,完成了register 通过ajax与后端的通信,今天主要完成数据与mongodb的存取,实现注册 / 登录 /
pojo.vo.po.domain区别
LiaoJuncai
java VO POJO javabean domain
POJO = "Plain Old Java Object",是MartinFowler等发明的一个术语,用来表示普通的Java对象,不是JavaBean, EntityBean 或者 SessionBean。POJO不但当任何特殊的角色,也不实现任何特殊的Java框架的接口如,EJB, JDBC等等。
即POJO是一个简单的普通的Java对象,它包含业务逻辑
Windows Error Code
OhMyCC
windows
0 操作成功完成.
1 功能错误.
2 系统找不到指定的文件.
3 系统找不到指定的路径.
4 系统无法打开文件.
5 拒绝访问.
6 句柄无效.
7 存储控制块被损坏.
8 存储空间不足, 无法处理此命令.
9 存储控制块地址无效.
10 环境错误.
11 试图加载格式错误的程序.
12 访问码无效.
13 数据无效.
14 存储器不足, 无法完成此操作.
15 系
在storm集群环境下发布Topology
roadrunners
集群 storm topology spout bolt
storm的topology设计和开发就略过了。本章主要来说说如何在storm的集群环境中,通过storm的管理命令来发布和管理集群中的topology。
1、打包
打包插件是使用maven提供的maven-shade-plugin,详细见maven-shade-plugin。
<plugin>
<groupId>org.apache.maven.
为什么不允许代码里出现“魔数”
tomcat_oracle
java
在一个新项目中,我最先做的事情之一,就是建立使用诸如Checkstyle和Findbugs之类工具的准则。目的是制定一些代码规范,以及避免通过静态代码分析就能够检测到的bug。 迟早会有人给出案例说这样太离谱了。其中的一个案例是Checkstyle的魔数检查。它会对任何没有定义常量就使用的数字字面量给出警告,除了-1、0、1和2。 很多开发者在这个检查方面都有问题,这可以从结果
zoj 3511 Cake Robbery(线段树)
阿尔萨斯
线段树
题目链接:zoj 3511 Cake Robbery
题目大意:就是有一个N边形的蛋糕,切M刀,从中挑选一块边数最多的,保证没有两条边重叠。
解题思路:有多少个顶点即为有多少条边,所以直接按照切刀切掉点的个数排序,然后用线段树维护剩下的还有哪些点。
#include <cstdio>
#include <cstring>
#include <vector&