package com.joyin.idc.entity.util;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Table;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
import org.apache.poi.xddf.usermodel.chart.AxisCrossBetween;
import org.apache.poi.xddf.usermodel.chart.AxisCrosses;
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
import org.apache.poi.xddf.usermodel.chart.BarDirection;
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
import org.apache.poi.xddf.usermodel.chart.XDDFPieChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
import org.apache.poi.xwpf.usermodel.XWPFChart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFStyle;
import org.apache.poi.xwpf.usermodel.XWPFStyles;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import com.joyin.idc.entity.wordform.BarChartForm;
/**
*
* @Description 功能描述: POI操作word文档工具类
*
* @author Administrator
* @date 2021年3月24日 下午6:17:11
*
*/
public class PoiUtils {
private Map<String, Map<String, Object>> orderMap = new HashMap<String, Map<String, Object>>();
public void init(XWPFDocument document) {
//获取段落
List<XWPFParagraph> paras = document.getParagraphs();
for (int i = 0; i < paras.size(); i++) {
XWPFParagraph para = paras.get(i);
// System.out.println(para.getCTP());//得到xml格式
// System.out.println(para.getStyleID());//段落级别
// System.out.println(para.getParagraphText());//段落内容
String titleLvl = getTitleLvl(document, para);//获取段落级别
if ("a5".equals(titleLvl) || "HTML".equals(titleLvl) || "".equals(titleLvl) || null == titleLvl) {
titleLvl = "8";
}
if (null != titleLvl && !"".equals(titleLvl) && !"8".equals(titleLvl)) {
String t = titleLvl;
String orderCode = getOrderCode(titleLvl);//获取编号
String text = para.getParagraphText();
text = orderCode + " " + text;
List<XWPFRun> runs = para.getRuns();
int runSize = runs.size();
/**Paragrap中每删除一个run,其所有的run对象就会动态变化,即不能同时遍历和删除*/
int haveRemoved = 0;
for (int runIndex = 0; runIndex < runSize; runIndex++) {
para.removeRun(runIndex - haveRemoved);
haveRemoved++;
}
if ("1".equals(titleLvl)) {
setLevelTitle1(document, para, text);
}
if ("2".equals(titleLvl)) {
setLevelTitle2(document, para, text);
}
}
}
}
/**
* 设置一级标题内容及样式
*
* @param paragraph
* @param text
*/
public void setLevelTitle1(XWPFDocument document, XWPFParagraph paragraph, String text) {
/**1.将段落原有文本(原有所有的Run)全部删除*/
deleteRun(paragraph);
/**3.插入新的Run即将新的文本插入段落*/
XWPFRun createRun = paragraph.insertNewRun(0);
createRun.setText(text);
XWPFRun separtor = paragraph.insertNewRun(1);
/**两段之间添加换行*/
separtor.setText("\r");
createRun.setFontSize(16);
createRun.setFontFamily("黑体");
paragraph.setIndentationFirstLine(600);
paragraph.setSpacingAfter(20);
paragraph.setSpacingBefore(20);
//addCustomHeadingStyle(document, "标题1", 1);
paragraph.setStyle("标题1");
}
/**
* 设置二级标题内容及样式
*
* @param paragraph
* @param text
*/
public void setLevelTitle2(XWPFDocument document, XWPFParagraph paragraph, String text) {
deleteRun(paragraph);
/**3.插入新的Run即将新的文本插入段落*/
XWPFRun createRun = paragraph.insertNewRun(0);
createRun.setText(text);
XWPFRun separtor = paragraph.insertNewRun(1);
/**两段之间添加换行*/
separtor.setText("\r");
createRun.setFontSize(16);
createRun.setBold(true);
createRun.setFontFamily("楷体_GB2312");
paragraph.setIndentationFirstLine(600);
paragraph.setSpacingAfter(10);
paragraph.setSpacingBefore(10);
//addCustomHeadingStyle(document, "标题2", 2);
paragraph.setStyle("标题2");
}
/**
* 设置正文文本内容及样式
*
* @param paragraph 段落
* @param text 内容
* @param jiacu 是否加粗
*/
public static void setTextPro(XWPFParagraph paragraph, String text,boolean jiacu) {
//获取原样式
//String color = paragraph.getRuns().get(0).getColor();
int fontSize = paragraph.getRuns().get(0).getFontSize();
String fontFamily = paragraph.getRuns().get(0).getFontFamily();
UnderlinePatterns underline = paragraph.getRuns().get(0).getUnderline();
// int firstLineIndent = paragraph.getFirstLineIndent();
ParagraphAlignment alignment = paragraph.getAlignment();
int indentationFirstLine = paragraph.getIndentationFirstLine();
int spacingBefore = paragraph.getSpacingBefore();
int spacingAfter = paragraph.getSpacingAfter();
//删除原段落
deleteRun(paragraph);
/**3.插入新的Run即将新的文本插入段落*/
XWPFRun createRun = paragraph.insertNewRun(0);
createRun.setText(text);
XWPFRun separtor = paragraph.insertNewRun(1);
// createRun.setColor(color);
if (fontFamily==null) {
fontFamily="宋体";
}
// createRun.setFontFamily(fontFamily);
if (fontSize!=-1) {
createRun.setFontSize(fontSize);
}else {
createRun.setFontSize(12);
}
createRun.setUnderline(underline);
createRun.setBold(jiacu);
// paragraph.setFirstLineIndent(firstLineIndent);
paragraph.setAlignment(alignment);
paragraph.setIndentationFirstLine(indentationFirstLine);
if (spacingAfter!=-1) {
paragraph.setSpacingAfter(spacingAfter);
}
if (spacingBefore!=-1) {
paragraph.setSpacingBefore(spacingBefore);
}
}
/**
* 设置表格标题内容及样式
*
* @param paragraph
* @param text
*/
public void setTableOrChartTitle(XWPFParagraph paragraph, String text) {
/**1.将段落原有文本(原有所有的Run)全部删除*/
deleteRun(paragraph);
XWPFRun createRun = paragraph.insertNewRun(0);
createRun.setText(text);
XWPFRun separtor = paragraph.insertNewRun(1);
/**两段之间添加换行*/
separtor.setText("\r");
createRun.setFontFamily("楷体");
createRun.setFontSize(16);
createRun.setBold(true);
paragraph.setSpacingAfter(10);
paragraph.setSpacingBefore(10);
paragraph.setAlignment(ParagraphAlignment.CENTER);
}
public static void deleteRun(XWPFParagraph paragraph) {
/*1.将段落原有文本(原有所有的Run)全部删除*/
List<XWPFRun> runs = paragraph.getRuns();
int runSize = runs.size();
/*Paragrap中每删除一个run,其所有的run对象就会动态变化,即不能同时遍历和删除*/
int haveRemoved = 0;
for (int runIndex = 0; runIndex < runSize; runIndex++) {
paragraph.removeRun(runIndex - haveRemoved);
haveRemoved++;
}
}
/**
* Word中的大纲级别,可以通过getPPr().getOutlineLvl()直接提取,但需要注意,Word中段落级别,通过如下三种方式定义:
* 1、直接对段落进行定义;
* 2、对段落的样式进行定义;
* 3、对段落样式的基础样式进行定义。
* 因此,在通过“getPPr().getOutlineLvl()”提取时,需要依次在如上三处读取。
*
* @param doc
* @param para
* @return
*/
private String getTitleLvl(XWPFDocument doc, XWPFParagraph para) {
String titleLvl = "";
//判断该段落是否设置了大纲级别
CTP ctp = para.getCTP();
if (ctp != null) {
CTPPr pPr = ctp.getPPr();
if (pPr != null) {
if (pPr.getOutlineLvl() != null) {
return String.valueOf(pPr.getOutlineLvl().getVal());
}
}
}
//判断该段落的样式是否设置了大纲级别
if (para.getStyle() != null) {
if (doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl() != null) {
return String.valueOf(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl().getVal());
}
//判断该段落的样式的基础样式是否设置了大纲级别
if (doc.getStyles().getStyle(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal())
.getCTStyle().getPPr().getOutlineLvl() != null) {
String styleName = doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal();
return String.valueOf(doc.getStyles().getStyle(styleName).getCTStyle().getPPr().getOutlineLvl().getVal());
}
}
if (para.getStyleID() != null) {
return para.getStyleID();
}
return titleLvl;
}
public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
if (cellIndex == fromCell) {
// The first merged cell is set with RESTART merge value
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
} else {
// Cells which join (merge) the first one, are set with CONTINUE
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
}
}
}
/**
* 获取标题编号
*
* @param titleLvl
* @return
*/
private String getOrderCode(String titleLvl) {
String order = "";
if ("0".equals(titleLvl) || Integer.parseInt(titleLvl) == 8) {//文档标题||正文
return "";
} else if (Integer.parseInt(titleLvl) > 0 && Integer.parseInt(titleLvl) < 8) {//段落标题
//设置最高级别标题
Map<String, Object> maxTitleMap = orderMap.get("maxTitleLvlMap");
if (null == maxTitleMap) {//没有,表示第一次进来
//最高级别标题赋值
maxTitleMap = new HashMap<String, Object>();
maxTitleMap.put("lvl", titleLvl);
orderMap.put("maxTitleLvlMap", maxTitleMap);
} else {
String maxTitleLvl = maxTitleMap.get("lvl") + "";//最上层标题级别(0,1,2,3)
if (Integer.parseInt(titleLvl) < Integer.parseInt(maxTitleLvl)) {//当前标题级别更高
maxTitleMap.put("lvl", titleLvl);//设置最高级别标题
orderMap.put("maxTitleLvlMap", maxTitleMap);
}
}
//查父节点标题
int parentTitleLvl = Integer.parseInt(titleLvl) - 1;//父节点标题级别
Map<String, Object> cMap = orderMap.get(titleLvl);//当前节点信息
Map<String, Object> pMap = orderMap.get(parentTitleLvl + "");//父节点信息
if (0 == parentTitleLvl) {//父节点为文档标题,表明当前节点为1级标题
int count = 0;
//最上层标题,没有父节点信息
if (null == cMap) {//没有当前节点信息
cMap = new HashMap<String, Object>();
} else {
count = Integer.parseInt(String.valueOf(cMap.get("cCount")));//当前序个数
}
count++;
order = count + "";
cMap.put("cOrder", order);//当前序
cMap.put("cCount", count);//当前序个数
orderMap.put(titleLvl, cMap);
} else {//父节点为非文档标题
int count = 0;
//如果没有相邻的父节点信息,当前标题级别自动升级
if (null == pMap) {
return getOrderCode(String.valueOf(parentTitleLvl));
} else {
String pOrder = String.valueOf(pMap.get("cOrder"));//父节点序
if (null == cMap) {//没有当前节点信息
cMap = new HashMap<String, Object>();
} else {
count = Integer.parseInt(String.valueOf(cMap.get("cCount")));//当前序个数
}
count++;
order = pOrder + "." + count;//当前序编号
cMap.put("cOrder", order);//当前序
cMap.put("cCount", count);//当前序个数
orderMap.put(titleLvl, cMap);
}
}
//字节点标题计数清零
int childTitleLvl = Integer.parseInt(titleLvl) + 1;//子节点标题级别
Map<String, Object> cdMap = orderMap.get(childTitleLvl + "");//
if (null != cdMap) {
cdMap.put("cCount", 0);//子节点序个数
orderMap.get(childTitleLvl + "").put("cCount", 0);
}
}
return order;
}
/**
* 为表格插入数据,行数不够添加新行
* @param table 需要插入数据的表格
* @param tableList 第四个表格的插入数据
* @param daList 第二个表格的插入数据
* @param type 表格类型:1-第一个表格 2-第二个表格 3-第三个表格 4-第四个表格
*/
public static void insertTable(XWPFTable table,List<String[]> daList,Integer type){
List<XWPFTableRow> rows = table.getRows();
List<XWPFTableCell> cellss = rows.get(rows.size()-1).getTableCells();
int tableLength=cellss.size();//表格的列数
//创建行和创建需要的列
for(int i = 0; i < daList.size(); i++){
XWPFTableRow row =null;
if(type==2||type==3||type==4||type==5||type==8||type==9||type==10) {
row = table.insertNewTableRow(2);//添加一个新行
}else {
row = table.insertNewTableRow(1);
}
for(int j = 0; j< tableLength; j++)
{
XWPFTableCell col= row.createCell();//添加一列
}
}
//创建行,根据需要插入的数据添加新行,不处理表头
for(int i = 0; i < daList.size(); i++){
List<XWPFTableCell> cells=null;
if(type==2||type==3||type==4||type==5||type==8||type==9||type==10) {
if(table.getRow(i+2)!=null) {
cells = table.getRow(i+2).getTableCells();
}
}
else {
cells = table.getRow(i+1).getTableCells();
}
for(int j = 0; j < cells.size(); j++){
XWPFTableCell cell02 = cells.get(j);
cell02.setText(daList.get(i)[j]);
}
}
}
/**
* 判断文本中时候包含$
* @param text 文本
* @return 包含返回true,不包含返回false
*/
public static boolean checkText(String text){
boolean check = false;
if(text.indexOf("$")!= -1){
check = true;
}
return check;
}
/**
* 匹配传入信息集合与模板
* @param value 模板需要替换的区域
* @param textMap 传入信息集合
* @return 模板需要替换区域信息集合对应值
*/
public static Object changeValue(String value, Map<String, Object> textMap){
Set<Entry<String, Object>> textSets = textMap.entrySet();
Object valu = "";
for (Entry<String, Object> textSet : textSets) {
//匹配模板与替换值 格式${key}
String key = textSet.getKey();
if(value.indexOf(key)!= -1){
valu = textSet.getValue();
}
}
return valu;
}
/**
* 将输入流中的数据写入字节数组
* @param in
* @return
*/
public static byte[] inputStream2ByteArray(InputStream in,boolean isClose){
byte[] byteArray = null;
try {
int total = in.available();
byteArray = new byte[total];
in.read(byteArray);
} catch (IOException e) {
e.printStackTrace();
}finally{
if(isClose){
try {
in.close();
} catch (Exception e2) {
System.out.println("关闭流失败");
}
}
}
return byteArray;
}
/**
* 合并行
* @param table
* @param col 需要合并的列
* @param fromRow 开始行
* @param toRow 结束行
*/
public static void mergeCellVertically(XWPFTable table, int col, int fromRow, int toRow) {
for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++){
CTVMerge vmerge = CTVMerge.Factory.newInstance();
if(rowIndex == fromRow){
vmerge.setVal(STMerge.RESTART);
} else {
vmerge.setVal(STMerge.CONTINUE);
}
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
CTTcPr tcPr = cell.getCTTc().getTcPr();
if (tcPr != null) {
tcPr.setVMerge(vmerge);
} else {
tcPr = CTTcPr.Factory.newInstance();
tcPr.setVMerge(vmerge);
cell.getCTTc().setTcPr(tcPr);
}
}
}
/**
* 获取需要合并单元格的下标
* @return
*/
public static List<Integer[]> startEnd(List<String[]> daList){
List<Integer[]> indexList = new ArrayList<Integer[]>();
List<String> list = new ArrayList<String>();
for (int i=0;i<daList.size();i++){
list.add(daList.get(i)[0]);
}
Map<Object, Integer> tm = new HashMap<Object, Integer>();
for (int i=0;i<daList.size();i++){
if (!tm.containsKey(daList.get(i)[0])) {
tm.put(daList.get(i)[0], 1);
} else {
int count = tm.get(daList.get(i)[0]) + 1;
tm.put(daList.get(i)[0], count);
}
}
for (Map.Entry<Object, Integer> entry : tm.entrySet()) {
String key = entry.getKey().toString();
String value = entry.getValue().toString();
if (list.indexOf(key) != (-1)){
Integer[] index = new Integer[2];
index[0] = list.indexOf(key);
index[1] = list.lastIndexOf(key);
indexList.add(index);
}
}
return indexList;
}
/**
* 创建普通柱状图-簇状柱状图-堆叠柱状图
*
* @param chart 图表对象
* @param barChartForm 数据对象
*/
public static void createBarChart(XWPFChart chart, BarChartForm barChartForm) throws Exception {
String[] categories = barChartForm.getCategories();
List<Double[]> tableData = barChartForm.getTableData();
List<String> colorTitles = barChartForm.getColorTitles();
String title = barChartForm.getTitle();
if (colorTitles.size() != tableData.size()) {
throw new Exception("颜色标题个数,必须和数组个数相同");
}
for (Double[] tableDatum : tableData) {
if (tableDatum.length != categories.length) {
throw new Exception("每个数组的元素个数,必须和");
}
}
// 设置标题
chart.setTitleText(title);
//标题覆盖
chart.setTitleOverlay(true);
// 处理对应的数据
int numOfPoints = categories.length;
String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
List<XDDFChartData.Series> seriesList = new ArrayList<XDDFChartData.Series>();
// 创建一些轴
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setTitle(barChartForm.getBottomTitle());
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setTitle(barChartForm.getBottomTitle());
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
// 创建柱状图的类型
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
// 为图表添加数据
for (int i = 0; i < tableData.size(); i++) {
XDDFChartData.Series series = data.addSeries(categoriesData, XDDFDataSourcesFactory.fromArray(
tableData.get(i), chart.formatRange(new CellRangeAddress(1, numOfPoints, i, i))));
seriesList.add(series);
}
for (int i = 0; i < seriesList.size(); i++) {
seriesList.get(i).setTitle(colorTitles.get(i), setTitleInDataSheet(chart, colorTitles.get(i), 1));
}
/*
* // 指定为簇状柱状图 if (tableData.size() > 1) { ((XDDFBarChartData)
* data).setBarGrouping(barChartForm.getGrouping());
* chart.getCTChart().getPlotArea().getBarChartArray(0).addNewOverlap().setVal(
* barChartForm.getNewOverlap()); }
*/
if (tableData.size() > 0) {
//((XDDFBarChartData) data).setBarGrouping(barChartForm.getGrouping());
//chart.getCTChart().getPlotArea().getBarChartArray(0).addNewOverlap().setVal(barChartForm.getNewOverlap());
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0).addNewDLbls();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
}
// 指定系列颜色
for (BarChartForm.ColorCheck colorCheck : barChartForm.getList()) {
XDDFSolidFillProperties fillMarker = new XDDFSolidFillProperties(colorCheck.getXddfColor());
XDDFShapeProperties propertiesMarker = new XDDFShapeProperties();
// 给对象填充颜色属性
propertiesMarker.setFillProperties(fillMarker);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(colorCheck.getNum()).addNewSpPr().set(propertiesMarker.getXmlObject());
}
((XDDFBarChartData) data).setBarDirection(BarDirection.COL);
// 设置多个柱子之间的间隔
// 绘制图形数据
chart.plot(data);
// create legend
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.TOP);
legend.setOverlay(false);
}
public static void createPieChart(XWPFChart chart, BarChartForm barChartForm) throws Exception {
String[] categories = barChartForm.getCategories();
List<Double[]> tableData = barChartForm.getTableData();
List<String> colorTitles = barChartForm.getColorTitles();
String title = barChartForm.getTitle();
if (colorTitles.size() != tableData.size()) {
throw new Exception("颜色标题个数,必须和数组个数相同");
}
/*
* for (Double[] tableDatum : tableData) { if (tableDatum.length !=
* categories.length) { throw new Exception("每个数组的元素个数,必须和"); } }
*/
// 设置标题
chart.setTitleText(title);
//标题覆盖
chart.setTitleOverlay(false);
// 处理对应的数据
int numOfPoints = categories.length;
String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
List<XDDFChartData.Series> seriesList = new ArrayList<XDDFChartData.Series>();
// 创建饼图的类型
XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);
// 为图表添加数据
for (int i = 0; i < tableData.size(); i++) {
XDDFChartData.Series series = data.addSeries(categoriesData, XDDFDataSourcesFactory.fromArray(
tableData.get(i), chart.formatRange(new CellRangeAddress(1, numOfPoints, i, i))));
seriesList.add(series);
}
for (int i = 0; i < seriesList.size(); i++) {
seriesList.get(i).setTitle(colorTitles.get(i), setTitleInDataSheet(chart, colorTitles.get(i), 1));
}
if (tableData.size() > 0) {
chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).addNewDLbls();
chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(false);//数据的值
chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);//小点点
chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);//类型
chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
//chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewNumFmt().
}
// 指定系列颜色
for (BarChartForm.ColorCheck colorCheck : barChartForm.getList()) {
XDDFSolidFillProperties fillMarker = new XDDFSolidFillProperties(colorCheck.getXddfColor());
XDDFShapeProperties propertiesMarker = new XDDFShapeProperties();
// 给对象填充颜色属性
propertiesMarker.setFillProperties(fillMarker);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(colorCheck.getNum()).addNewSpPr().set(propertiesMarker.getXmlObject());
}
// ((XDDFPieChartData) data).setBarDirection(BarDirection.COL);
// 设置多个柱子之间的间隔
// 绘制图形数据
chart.plot(data);
// create legend图例位置
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.TOP);
legend.setOverlay(false);
}
static CellReference setTitleInDataSheet(XWPFChart chart, String title, int column) throws Exception {
XSSFWorkbook workbook = chart.getWorkbook();
XSSFSheet sheet = workbook.getSheetAt(0);
XSSFRow row = sheet.getRow(0);
if (row == null)
row = sheet.createRow(0);
XSSFCell cell = row.getCell(column);
if (cell == null)
cell = row.createCell(column);
cell.setCellValue(title);
return new CellReference(sheet.getSheetName(), 0, column, true, true);
}
public static void setTableStyle(XWPFTable table) {
CTTblBorders borders = table.getCTTbl().getTblPr().addNewTblBorders();
CTBorder hBorder = borders.addNewInsideH();
hBorder.setVal(STBorder.Enum.forString("single")); // 线条类型
hBorder.setSz(new BigInteger("1")); // 线条大小
hBorder.setColor("000000"); // 设置颜色
CTBorder vBorder = borders.addNewInsideV();
vBorder.setVal(STBorder.Enum.forString("single"));
vBorder.setSz(new BigInteger("1"));
vBorder.setColor("000000");
CTBorder lBorder = borders.addNewLeft();
lBorder.setVal(STBorder.Enum.forString("single"));
lBorder.setSz(new BigInteger("1"));
lBorder.setColor("000000");
CTBorder rBorder = borders.addNewRight();
rBorder.setVal(STBorder.Enum.forString("single"));
rBorder.setSz(new BigInteger("1"));
rBorder.setColor("000000");
CTBorder tBorder = borders.addNewTop();
tBorder.setVal(STBorder.Enum.forString("single"));
tBorder.setSz(new BigInteger("1"));
tBorder.setColor("000000");
CTBorder bBorder = borders.addNewBottom();
bBorder.setVal(STBorder.Enum.forString("single"));
bBorder.setSz(new BigInteger("1"));
bBorder.setColor("000000");
}
}