2021-06-11 java POi导出word文档用到的工具类,包括饼状图,柱状图,以及表格的跨行跨列

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");
    }
            

}
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Java POI 是一个用于操作 Microsoft Office 格式文件的 Java 库,包括 Word、Excel 和 PowerPoint 等文件。在 Java 中使用 POI 库可以方便地读取、修改和创建 Office 文件。 在使用 POI 导出 Word 文档时,需要先创建一个空的 Word 文档,然后向其中添加内容。可以使用 POI 提供的 XWPFDocument 类来创建 Word 文档对象,使用 XWPFParagraph 类来创建段落对象,使用 XWPFRun 类来创建文本对象。 在创建段落对象时,可以设置段落的样式,如字体、字号、颜色、对齐方式等。在创建文本对象时,可以设置文本的样式,如加粗、斜体、下划线等。 除了文本内容,还可以向 Word 文档中添加表格、图片、超链接等元素。可以使用 POI 提供的 XWPFTable 类来创建表格对象,使用 XWPFTableRow 和 XWPFTableCell 类来创建表格行和单元格对象。可以使用 XWPFParagraph 类的 addPicture 方法来添加图片,使用 XWPFHyperlink 类来添加超链接。 最后,将创建好的 Word 文档保存到本地文件系统或输出流中即可。可以使用 XWPFDocument 类的 write 方法将文档保存到文件中,使用 XWPFDocument 类的 write 方法将文档输出到输出流中。 总之,使用 Java POI 导出 Word 文档需要掌握 XWPFDocument、XWPFParagraph、XWPFRun、XWPFTable、XWPFTableRow、XWPFTableCell、XWPFHyperlink 等类的使用方法,以及如何设置样式、添加元素和保存文档。 ### 回答2: Java POI是一个流行的Java库,它提供了对微软Office格式的读取和写入支持,其中包括Word文档导出。在使用此库导出Word文档时,可以按照以下步骤进行操作: 第一步:导入所需的库文件和工具 我们需要导入Apache POI库以及相关的库文件来使用Java POI。可以从maven中央仓库中下载这些库文件,也可以通过其他方式来获取这些文件。在项目中添加所需的库文件,并在相关的类中导入这些库文件。 第二步:创建Word文档Java中,可以使用XWPFDocument类来创建一个空白的Word文档。在此类中,可以添加标题,正文文本,表格等内容,以构建新的Word文档。可以使用以下代码来创建一个新的Word文档。 XWPFDocument doc = new XWPFDocument(); 第三步:添加内容 在Java POI中,可以使用XWPFParagraph类来添加Word文档中的段落。可以使用此类来添加文字,图片等。以下是如何使用XWPFParagraph类来添加段落的示例代码: XWPFParagraph para = doc.createParagraph(); XWPFRun run = para.createRun(); run.setText("这是一个段落"); 可以使用XWPFTable类来添加Word文档中的表格。以下是如何使用XWPFTable类来添加表格的示例代码: XWPFTable table = doc.createTable(); XWPFTableRow row = table.getRow(0); row.getCell(0).setText("第一行第一列"); row.addNewTableCell().setText("第一行第二列"); 第四步:保存文档 完成了Word文档的创建和内容添加之后,需要将其保存到磁盘上。可以使用FileOutputStream类和XWPFDocument类的write() 方法来完成保存。以下代码片段演示了如何将文档保存到磁盘上: FileOutputStream outputStream = new FileOutputStream(new File("output.docx")); doc.write(outputStream); outputStream.close(); 总结 Java POI提供了一种通过代码来创建和编辑Word文档的方式。使用Java POI,我们可以创建空白的Word文档,向文档中添加内容,例如文字,图片和表格。最后,我们可以将文档保存到磁盘上。通过这些步骤,我们可以轻松地使用Java POI导出Word文档。 ### 回答3: Java POI是一个开源的Java库,用于处理各种Microsoft Office格式文件,包括Word文档(.docx)、Excel表格(.xlsx)和PowerPoint演示文稿(.pptx)。在Java POI中,我们可以使用XWPFDocument对象导出Word文档。 1. 导入依赖 在使用Java POI库之前,首先必须要引入相应的依赖包。我们需要使用以下依赖: ``` <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> ``` 2. 创建一个Word文档 我们可以使用XWPFDocument类创建一个新的Word文档。默认情况下,文档中没有任何内容: ``` XWPFDocument document = new XWPFDocument(); ``` 3. 添加标题 添加标题可以使用XWPFParagraph和XWPFRun类。XWPFParagraph用于存储段落内容,而XWPFRun用于添加样式。以下是一个添加标题的示例代码: ``` XWPFParagraph titlePara = document.createParagraph(); XWPFRun titleRun = titlePara.createRun(); titleRun.setBold(true); titleRun.setFontSize(16); titleRun.setText("这是一个标题"); ``` 4. 添加正文 添加正文和添加标题类似,只不过我们可以在添加文本之前使用setBold、setItalic、setUnderline等方法设置样式。以下是添加正文的示例代码: ``` XWPFParagraph contentPara = document.createParagraph(); XWPFRun contentRun = contentPara.createRun(); contentRun.setFontSize(12); contentRun.setText("这是一个正文"); ``` 5. 添加图片 在Word文档中添加图片可以使用XWPFRun类的addPicture方法。需要注意的是,图片必须先被转换为byte数组。以下是添加图片的示例代码: ``` // 读取图片文件 FileInputStream fis = new FileInputStream("path/to/image.png"); byte[] imageData = IOUtils.toByteArray(fis); fis.close(); // 添加图片 XWPFParagraph imagePara = document.createParagraph(); XWPFRun imageRun = imagePara.createRun(); imageRun.addPicture(new ByteArrayInputStream(imageData), XWPFDocument.PICTURE_TYPE_PNG, "image.png", Units.toEMU(300), Units.toEMU(200)); ``` 6. 保存文档 在完成文档的内容添加后,我们可以将文档保存到指定的文件中。以下是保存文档的示例代码: ``` OutputStream os = new FileOutputStream("path/to/output.docx"); document.write(os); os.close(); document.close(); ``` 以上就是使用Java POI导出Word文档的详细步骤。通过使用Java POI,我们可以方便地创建和编辑Word文档,并将其保存为docx格式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值