java poi生成word

package com.cmft.fhrms.business.common.utils;

import com.cmft.fhrms.business.common.anno.Word;
import com.cmft.fhrms.business.common.model.dto.MergeWordColumnDto;
import com.cmft.fhrms.business.common.model.dto.MergeWordRowDto;
import com.cmft.fhrms.business.common.model.dto.WordTableCellDto;
import com.cmft.fhrms.utils.CommonUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static com.cmft.fhrms.business.common.constant.WordConstant.TimesNewRoman;

/**
 * @Description: word 报告表格设置操作
 * @Datetime: 2023/12/15 11:02
 * @Version: 1.0
 */
public class WordUtil<T> {

    /**
     * @Description 设置文本内容
      * @param doc 文本对象
     * @param text 文字内容
     * @param fontFamily 字体类型
     * @param fontSize 字体大小
     * @param isBold 是否加粗
     * @param align 字体位置
     * @param align 行间距 
     * @param firstLine 首行缩进长度
     * @return void
     */
    public void createWordText(XWPFDocument doc, String text, String fontFamily, int fontSize, Boolean isBold,
                                ParagraphAlignment align, int lineSpace, int firstLine) {
        XWPFParagraph paras = createXWPFParagraph(doc, align, lineSpace, firstLine);
        XWPFRun run = createWordText(paras, text, fontFamily, fontSize, isBold);
    }

    /**
     * 创建段落
     * @param doc 文本对象
     * @param align 字体位置
     * @param lineSpace 行间距
     * @param firstLine 首行缩进长度
     * @return
     */
    public XWPFParagraph createXWPFParagraph(XWPFDocument doc, ParagraphAlignment align, int lineSpace, int firstLine) {
        XWPFParagraph paras = doc.createParagraph();
        paras.setAlignment(align);
        //设置行间距
        setLineSpace(paras, lineSpace);
        //设置首行缩进
        setFirstLine(paras, firstLine);
        return paras;
    }

    /**
     * 设置行间距
     * @param paras 段落对象
     * @param size 行间距大小 磅数,例30磅size传30
     */
    private void setLineSpace(XWPFParagraph paras, int size) {
        CTP ctp = paras.getCTP();
        CTPPr ppr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
        CTSpacing spacing = ppr.isSetSpacing() ? ppr.getSpacing() : ppr.addNewSpacing();
        spacing.setAfter(BigInteger.valueOf(0));
        spacing.setBefore(BigInteger.valueOf(0));
        spacing.setLineRule(STLineSpacingRule.EXACT);
        //1磅数是20
        spacing.setLine(BigInteger.valueOf(size * 20));
    }

    /**
     * 设置首行缩进
     * @param paras 段落对象
     * @param size 字符数,例如2个字符,size为2
     */
    private void setFirstLine(XWPFParagraph paras, int size) {
        CTP ctp = paras.getCTP();
        CTPPr ppr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
        CTInd ctInd = ppr.isSetInd() ? ppr.getInd() : ppr.addNewInd();
        ctInd.setFirstLineChars(BigInteger.valueOf(size * 100));
    }

    /**
     * 设置文本内容
     * @param paras 段落对象
     * @param text 文字内容
     * @param fontFamily 字体类型
     * @param fontSize 字体大小
     * @param isBold 是否加粗
     */
    public XWPFRun createWordText(XWPFParagraph paras, String text, String fontFamily, int fontSize, Boolean isBold) {
        XWPFRun run = paras.createRun();
        run.setText(text);
        if (fontFamily != null) {
            run.setFontFamily(fontFamily);
        }
        setNumberFontIsNewRoman(run,text);
        if (fontSize != 0) {
            run.setFontSize(fontSize);
        }
        run.setBold(isBold);
        return run;
    }

    /**
     * @Description 设置word报告表格,既支持单级表头,又支持多级表头
     * @param doc 文档对象
     * @param dataList 数据集
     * @param columnNameList 表头集合
     * @param mergeColumnList 合并列索引集合
     * @param mergeRowList 合并行索引集合
     * @return void
     */
    public void setWordTable(XWPFDocument doc, List<T> dataList, List<List<String>> columnNameList, List<MergeWordColumnDto> mergeColumnList,
                                    List<MergeWordRowDto> mergeRowList, WordTableCellDto tableCellDto) throws Exception{
        //创建段落对象,内容居中展示
        XWPFParagraph paras = doc.createParagraph();
        paras.setAlignment(ParagraphAlignment.CENTER);
        //获取游标
        XmlCursor cursor = paras.getCTP().newCursor();
        //在指定游标位置插入表格
        XWPFTable table = doc.insertNewTbl(cursor);
        //1.处理表头部分
        Map<Integer,String> headNameMap = new HashMap<>();
        for (List<String> rowList : columnNameList) {
            //1.1表头值设置
            XWPFTableRow row = table.getRow(columnNameList.indexOf(rowList));
            if(null == row) {
                row = table.createRow();
            }
            for(int i = 0;i < rowList.size();i++) {
                String columnName = rowList.get(i);
                XWPFTableCell cell = row.getCell(i);
                if(null == cell) {
                    cell = row.createCell();
                }
                setCellValue(cell, columnName, tableCellDto);
                if (StringUtils.isNotBlank(columnName)) {
                    headNameMap.put(rowList.indexOf(columnName), columnName);
                }
            }
        }
        //表头样式设置
        setTableHeadColumStyle(table, dataList.get(0),headNameMap);

        //2.填充表格数据
        setTableData(table,dataList,headNameMap);
        //3.单元格合并
        if(CollectionUtils.isNotEmpty(mergeColumnList)) {
            for (MergeWordColumnDto item : mergeColumnList) {
                mergeCellsHorizontal(table, item.getRowIndex(), item.getFromCell(), item.getToCell());
            }
        }
        if(CollectionUtils.isNotEmpty(mergeRowList)) {
            for (MergeWordRowDto item : mergeRowList) {
                mergeCellsVertically(table, item.getCellIndex(), item.getFromRow(), item.getToRow());
            }
        }
    }

    /**
    * 设置表格表头样式
    */
    public void setTableHeadColumStyle(XWPFTable table,T t,Map<Integer,String> headNameMap) {
        for(XWPFTableRow row : table.getRows()) {
            for(XWPFTableCell cell : row.getTableCells()) {
                cell.getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER);
                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                //列宽设置
                int cellIndex = row.getTableCells().indexOf(cell);
                String headName = headNameMap.get(cellIndex);
                Field[] fields = t.getClass().getDeclaredFields();
                for (int j = 0; j < fields.length; j++) {
                    Field field = fields[j];
                    field.setAccessible(true);
                    Word word = field.getAnnotation(Word.class);
                    if (word != null && word.name().equals(headName)) {
                        CTTcPr tcpr = cell.getCTTc().addNewTcPr();
                        CTTblWidth cellw = tcpr.addNewTcW();
                        cellw.setType(STTblWidth.DXA);
                        cellw.setW(BigInteger.valueOf(360L *word.columnWith()));
                    }
                }
            }
            row.setHeight(20);
        }
    }

    /**
     * @Description 填充表格数据
     * @param table 表格对象
     * @param dataList 数据集
     * @param headNameMap 表头集合
     * @return void
     */
    public void setTableData(XWPFTable table, List<T> dataList, Map<Integer,String> headNameMap) throws Exception{
        if (CollectionUtils.isNotEmpty(dataList)) {
            table.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE, 1, 0, "000000");
            table.setInsideVBorder(XWPFTable.XWPFBorderType.SINGLE, 1, 0, "000000");
            // XWPFTable没有设置外边框的方法,需要使用CTTblPr进行设置
            addOutSideBorder(table);
            // 遍历集合数据,产生数据行
            Iterator<T> it = dataList.iterator();
            while (it.hasNext()) {
                XWPFTableRow row = table.createRow();
                row.setHeight(15);// 设置行高(最小值)
                T t = it.next();
                Field[] fields = t.getClass().getDeclaredFields();
                for(int i = 0;i < headNameMap.size();i++) {
                    String headName = headNameMap.get(i);
                    if(null != headName) {
                        XWPFTableCell cell = row.getCell(i);
                        if(null == cell) {
                            cell = row.createCell();
                        }
                        XWPFRun run = cell.getParagraphs().get(0).createRun();
                        for (int j = 0; j < fields.length; j++) {
                            Field field = fields[j];
                            field.setAccessible(true);
                            Word word = field.getAnnotation(Word.class);
                            if (word != null && word.name().equals(headName)) {
                                Object value = field.get(t);
                                if (value != null) {
                                    String text = value.toString();
                                    run.setText(text);
                                    run.setFontFamily(word.fontFamily());
                                    setNumberFontIsNewRoman(run,text);
                                    run.setFontSize(word.fontSize());
                                    cell.getParagraphs().get(0).setAlignment(word.alignment());
                                    cell.getParagraphs().get(0).setWordWrapped(true);
                                }
                                //设置表格列宽
                                CTTcPr tcpr = cell.getCTTc().addNewTcPr();
                                CTTblWidth cellw = tcpr.addNewTcW();
                                cellw.setType(STTblWidth.DXA);
                                cellw.setW(BigInteger.valueOf(360L *word.columnWith()));
                            }
                        }
                    }
                }
                //设置单元格内容居中展示
                row.getTableCells().forEach(cell -> {
                    cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                });
            }
        }
    }

    /**
    * 设置数字字体为新罗马
    */
    private void setNumberFontIsNewRoman(XWPFRun run,String text) {
        for(char c : text.toCharArray()) {
            if(CommonUtil.isNumber(String.valueOf(c))){
                run.setFontFamily(TimesNewRoman);
                break;
            }
        }
    }

    /**
    *  word表格 设置单元格值
    */
    public void setCellValue(XWPFTableCell cell,String text, WordTableCellDto tableCellDto) {
        XWPFRun run = cell.getParagraphs().get(0).createRun();
        run.setText(text);
        if (tableCellDto.getFontFamily() != null) {
            run.setFontFamily(tableCellDto.getFontFamily());
        }
        if (tableCellDto.getFontSize() != 0) {
            run.setFontSize(tableCellDto.getFontSize());
        }
        run.setBold(tableCellDto.getIsBold());
        run.setColor(tableCellDto.getRunColor());
        cell.setColor(tableCellDto.getCellColor());
    }

    /**
    *  word表格 设置外边框
    */
    public void addOutSideBorder(XWPFTable table) {
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        CTTblBorders ctb = tblPr.addNewTblBorders();
        CTBorder[] borders = {ctb.addNewTop(), ctb.addNewBottom(), ctb.addNewLeft(), ctb.addNewRight()};
        for (CTBorder b : borders) {
            b.setVal(STBorder.Enum.forInt(STBorder.INT_SINGLE));
            b.setSz(BigInteger.valueOf(1));
            b.setColor("000000");
        }
    }


    /**
     *  word表格 合并列操作
     */
    public void mergeCellsHorizontal(XWPFTable table,int rowIndex,int fromCell,int toCell){
        for(int cellIndex = fromCell; cellIndex <= toCell; cellIndex ++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(cellIndex);
            if(cellIndex == fromCell) {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            }else {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
     * word表格 合并行操作
     */
    public void mergeCellsVertically(XWPFTable table, int cellIndex, int fromRow, int toRow){
        for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex ++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(cellIndex);
            if(rowIndex == fromRow) {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            }else {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
    * 文档中 表格单元格内容换行处理
    */
    public void tableTextAddBreak(XWPFDocument doc){
        //遍历所有表格
        for(XWPFTable table : doc.getTables()) {
            for(XWPFTableRow row : table.getRows()) {
                for(XWPFTableCell cell : row.getTableCells()) {
                    //单元格 : 直接cell.setText()只会把文字加在原有的后面,删除不了文字
                    addBreakInCell(cell);
                }
            }
        }
    }

    private  void addBreakInCell(XWPFTableCell cell) {
        if(cell.getText() != null && cell.getText().contains("\n")) {
            for (XWPFParagraph paragraph : cell.getParagraphs()) {
                for (XWPFRun run : paragraph.getRuns()) {
                    if(run.getText(0)!= null && run.getText(0).contains("\n")) {
                        String[] lines = run.getText(0).split("\n");
                        if(lines.length > 0) {
                            run.setText(lines[0], 0);
                            for(int i=1;i<lines.length;i++){
                                run.addBreak();
                                run.setText(lines[i]);
                            }
                        }
                    }
                }
            }
        }
    }

}

private XWPFDocument generateDataWord(TaskParamDto paramDto, MessagePushInfoDto pushInfo) throws Exception{
        try{
            String templateName = "招商金控风险信息推送情况月报模板.docx";
            InputStream inputStream = this.getClass().getResourceAsStream("/templates/" + templateName);
            XWPFDocument doc = new XWPFDocument(inputStream);
            
			WordUtil wordUtil = new WordUtil();
			return doc;
            } catch (Exception e) {
            log.error("ScheduleMessageWordGenerateTask generateDataWord error:",e);
            throw new BusinessException("4.生成消息推送报告异常");
        }
    }
            
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 Apache POIJava生成 Word 文档目录,您需要按照以下步骤进行操作: 1. 创建一个新的 Word 文档对象。 ```java XWPFDocument document = new XWPFDocument(); ``` 2. 向文档中添加标题和内容。 ```java XWPFParagraph title = document.createParagraph(); XWPFRun titleRun = title.createRun(); titleRun.setText("标题"); XWPFParagraph content = document.createParagraph(); XWPFRun contentRun = content.createRun(); contentRun.setText("内容"); ``` 3. 创建目录并设置样式。 ```java CTP ctp = CTP.Factory.newInstance(); CTSimpleField tocField = ctp.addNewFldSimple(); tocField.setInstr("TOC \\o \"1-3\" \\h \\z \\u"); // 设置目录样式 tocField.setDirty(STOnOff.TRUE); XWPFParagraph tocParagraph = new XWPFParagraph(ctp, document); tocParagraph.setAlignment(ParagraphAlignment.CENTER); // 居中对齐 document.createTOC().setTableOfContetsParagraph(tocParagraph); ``` 4. 保存文档到文件。 ```java FileOutputStream outputStream = new FileOutputStream("目录.docx"); document.write(outputStream); outputStream.close(); ``` 完整示例代码如下: ```java import org.apache.poi.xwpf.usermodel.*; import java.io.FileOutputStream; import java.io.IOException; public class WordTableOfContentsExample { public static void main(String[] args) { try { XWPFDocument document = new XWPFDocument(); // 添加标题和内容 XWPFParagraph title = document.createParagraph(); XWPFRun titleRun = title.createRun(); titleRun.setText("标题"); XWPFParagraph content = document.createParagraph(); XWPFRun contentRun = content.createRun(); contentRun.setText("内容"); // 创建目录并设置样式 CTP ctp = CTP.Factory.newInstance(); CTSimpleField tocField = ctp.addNewFldSimple(); tocField.setInstr("TOC \\o \"1-3\" \\h \\z \\u"); // 设置目录样式 tocField.setDirty(STOnOff.TRUE); XWPFParagraph tocParagraph = new XWPFParagraph(ctp, document); tocParagraph.setAlignment(ParagraphAlignment.CENTER); // 居中对齐 // 添加目录到文档 document.createTOC().setTableOfContetsParagraph(tocParagraph); // 保存文档到文件 FileOutputStream outputStream = new FileOutputStream("目录.docx"); document.write(outputStream); outputStream.close(); System.out.println("目录生成成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 这段代码创建了一个包含标题、内容和目录的 Word 文档。目录使用了预定义的样式,并设置为居中对齐。最后,将文档保存为名为 "目录.docx" 的文件。 请注意,生成目录需要使用 Apache POI 对应的版本(如 poi-ooxml)。确保您的项目中包含了正确的依赖项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值