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;
public class WordUtil<T> {
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);
}
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;
}
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);
spacing.setLine(BigInteger.valueOf(size * 20));
}
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));
}
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;
}
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);
Map<Integer,String> headNameMap = new HashMap<>();
for (List<String> rowList : columnNameList) {
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);
setTableData(table,dataList,headNameMap);
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);
}
}
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");
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;
}
}
}
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());
}
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");
}
}
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);
}
}
}
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()) {
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.生成消息推送报告异常");
}
}