替换方式插入合并单元格的表格到word

wylc123 1年前 ⋅ 633 阅读

效果:

模板文件:

生成报告效果:

多的不说直接上代码

/**
 * @Title: PrintTask.java
 * @Package com.example.job
 * @Description: TODO(用一句话描述该文件做什么)
 * @author tc
 * @date 2018年5月2日 上午11:14:07
 * @version V1.0
 */
package cnki.bdmsjob.task;

import cnki.bdms.common.util.HFSHelper;
import cnki.bdms.common.util.HttpClientHelper;
import cnki.bdmsjob.base.*;
import cnki.bdmsjob.config.ChromeDriverConf;
import cnki.bdmsjob.entity.EpidemicDataAppUsed;
import cnki.bdmsjob.entity.EpidemicDataSmsPush;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @ClassName: GovernmentInformationReportTask
 * @Description: 每周政务信息资源体系工作简报生成任务
 * @author songbin
 * @date 2021年05月18日 上午11:14:07
 *
 */
@Component
public class GovernmentInformationReportTask {
	protected static final Logger logger = LoggerFactory.getLogger(GovernmentInformationReportTask.class);
	//10秒调度一次
	//@Scheduled(cron="0/10 * * * * ? ")
	//每晚2点跑昨日数据秒调度一次
//	@Scheduled(cron="0 0 2 * * ? ")
	public void createWeekReport(){
		String today = "2021-05-18"; //DateUtil.getBeforeDay(DateUtil.getNowDate());
		createReport(today);
	}
	public static void createReport(String day){
		logger.info("开始生成当日疫情数据报送报告#####"+DateUtil.getTimeString());
//		HttpClientHelper.httpGet();
		String today = day;
		try {
			/**
			 * 获取防疫数据汇聚情况
			 * @return
			 */
			Map<String,Object> convergenceDatas = EpidemicDataUtil.getEpidemicDataConvergence(today);
			/**
			 * 防疫数据下发情况
			 * @return
			 */
			Map<String,Object> issuedDatas = EpidemicDataUtil.getEpidemicDataIssued(today);
			/**
			 * 向中高风险地区推送短信情况
			 * @return
			 */
			EpidemicDataSmsPush smsPushData = EpidemicDataUtil.getEpidemicDataSmsPush(today);

			/**
			 * “天府健康通”使用情况
			 * @return
			 */
			EpidemicDataAppUsed appUsedData = EpidemicDataUtil.getEpidemicDataAppUsed(today);
			//模板文件地址
			String initWordFile = null;
//			try {
//				//根据操作系统的不同,获取不同的上传路径
//				String os = System.getProperty("os.name");
//				if(os.toLowerCase().startsWith("win")){
//					initWordFile = ResourceUtils.getURL("classpath:static/wordmodel/江西农产品批发市场价格行情模板.docx").getPath().substring(1);
//				}else {
//					initWordFile = ResourceUtils.getURL("classpath:static/wordmodel/江西农产品批发市场价格行情模板.docx").getPath();
//				}
//			} catch (FileNotFoundException e) {
//				e.printStackTrace();
//			}
			initWordFile = ChromeDriverConf.wordmodelPath+"GovernmentInformationReportMode.docx";
			initWordFile = initWordFile.replaceAll("/", "\\\\\\\\");
			initWordFile = java.net.URLDecoder.decode(initWordFile,"utf-8");
			logger.info("模板文件地址:"+initWordFile);
			ExportWordUtil ew = new ExportWordUtil();
			XWPFDocument document = ew.createXWPFDocument(initWordFile);

			/*****************替换模板中的变量***************/
			Map<String, String> changeTxtMap = new HashMap<String, String>();
			changeTxtMap.put("smsnum", smsPushData.getNum().toString());
			changeTxtMap.put("endtime", DateUtil.formatZhDate(today));
			double jkmsuers = (double)appUsedData.getJkmsuers()/10000;
			changeTxtMap.put("jkmsuers", String.valueOf(jkmsuers));
			double rednum = (double)appUsedData.getRednum()/10000;
			changeTxtMap.put("rednum", String.valueOf(rednum));
			double yellownum = (double)appUsedData.getYellownum()/10000;
			changeTxtMap.put("yellownum", String.valueOf(yellownum));
			changeTxtMap.put("addrednumbyday", appUsedData.getAddrednumbyday().toString());
			changeTxtMap.put("addyellownumbyday", appUsedData.getAddyellownumbyday().toString());
			changeTxtMap.put("jwusers", appUsedData.getJwusers().toString());
			changeTxtMap.put("jwrednum", appUsedData.getJwrednum().toString());
			changeTxtMap.put("jwyellownum", appUsedData.getJwyellownum().toString());

			Map<String ,Map<String,Object>> tabMap = new HashMap<>();
			/******************************插入表格table01***************************************/
			tabMap.put("$table01",convergenceDatas);
//			//创建表格行数
//			int rows = Integer.valueOf(convergenceDatas.get("rows").toString());
//			//创建表格列数
//			int cols = Integer.valueOf(convergenceDatas.get("cols").toString());
//			//需要合并单元格的坐标
//			List<Map<String, Object>> verticallyMapList = (List<Map<String, Object>>) convergenceDatas.get("verticallyMapList");
//			//插入表格的格式数据
//			List<List<Object>> tabDataList = (List<List<Object>>) convergenceDatas.get("tabDataList");
//			XWPFTable infoTable = ew.createTableParagraph(document, rows, cols, verticallyMapList);//创建表格并合并单元格
//			ew.fillTableData(infoTable, tabDataList);
			/******************************表格table01数据加载完毕***************************************/

			/******************************插入表格table02***************************************/
			tabMap.put("$table02",issuedDatas);
			/******************************表格table02数据加载完毕***************************************/
			WorderToNewWordUtils.changeText(document,changeTxtMap,null,tabMap);
			/***************替换模板中的变量结束***************/
			//新生产的模板文件
			String hfsKey = UuidUtil.getUUID();
			String fileName = hfsKey + ".docx";
			String reportName = today + "数据报送";
			String memo = DateUtil.formatZhDate(today)+ "数据报送";
			String outputUrl = ChromeDriverConf.picSavePath + fileName;
			ew.saveDocument(document, outputUrl);
			//上传HFS,并记录数据库
			//上传到hfs
			try {
				boolean upflag = HFSHelper.upload(fileName, outputUrl);
				if (!upflag) {
					logger.info("报告文件" + fileName + "上传HFS失败!");
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException("上传文件失败");
			}

			//保存到表中 报告
			/*添加报告*/
			Date createTime = DateUtil.getDateNow();
			boolean flag_add = DailyPriceUtil.insertReport(reportName, ChromeDriverConf.dailyReportCategoryID, 4, 0, memo, "", createTime, hfsKey);
			if (flag_add) {
				logger.info("报告添加成功!");
				File file = new File(outputUrl);
				// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
				if (file.exists() && file.isFile()) {
						if (file.delete()) {
							logger.info("删除临时报告文件" + fileName + "成功!");
						} else {
							logger.info("删除临时报告文件" + fileName + "失败!");
						}
				} else {
					logger.info("删除临时报告文件失败:" + fileName + "不存在!");
				}
			} else {
				logger.error("报告添加失败!");
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage() + e.getStackTrace());
		}
	}
}
/**
 * @author SongBin on 2019/9/9.
 */
package cnki.bdmsjob.base;

import cnki.bdmsjob.db.MySqlHelper;
import cnki.bdmsjob.entity.*;
import cnki.bdmsjob.service.IEpidemicData;
import cnki.bdmsjob.service.ReportService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class EpidemicDataUtil {
    private static IEpidemicData sIEpidemicData;
    private static ReportService sReportService;
    private static Logger log = LoggerFactory.getLogger(EpidemicDataUtil.class);
    private static MySqlHelper mySqlHelper = new MySqlHelper();
    @Autowired
    IEpidemicData iEpidemicData;
    @Autowired
    ReportService reportService;
    @PostConstruct
    public void init(){
        this.sIEpidemicData = iEpidemicData;
        this.sReportService = reportService;
    }

    //蔬菜表格数据分析,描述
    public static Map<String,Object> getEpidemicDataConvergence(String day){
        log.info("获取某日某市当前疫情概况");
        EpidemicDataQuery query = new EpidemicDataQuery();
        query.setToday(day);
        List<EpidemicDataConvergence> list = sIEpidemicData.getEpidemicDataConvergence(query);
        //获取分类数组
        List<String> categorys = list.stream().map(EpidemicDataConvergence::getCategory).distinct().collect(Collectors.toList());
        Map<String,Object> result = new HashMap<>();
        int currentRow = 1; //表格当前数据行
        int rows = list.size()+1; //表格行数(加上表格头行)
        int cols = 4; //表格列数
        List<Map<String,Integer>> verticallyMapList = new ArrayList<>();//需要合并的行的坐标
        for(String category : categorys) {
            Map verticallyMap = new HashMap();
            verticallyMap.put("pname", category);
            verticallyMap.put("col", 0);
            verticallyMap.put("fromRow", currentRow);
            int rowConut = (int)list.stream().filter(m->m.getCategory().equals(category)).count();
            verticallyMap.put("toRow", currentRow + rowConut - 1);
            verticallyMapList.add(verticallyMap);
            currentRow = currentRow + rowConut;
        }
        //表格每行数据
        List<List<Object>> tabDataList = new ArrayList<>();
        int count = 0;
        for (EpidemicDataConvergence ptd : list) {
            if(count == 0){
                //添加表头数据
                List<Object> theadList = new ArrayList<Object>();
                theadList.add("数据分类");
                theadList.add("具体内容");
                theadList.add("数据量");
                theadList.add("下发单位");
                tabDataList.add(theadList);
            }
            if(count<list.size()) {
                List<Object> tempList = new ArrayList<Object>();
                tempList.add(ptd.getCategory());
                tempList.add(ptd.getContent());
                tempList.add(ptd.getDatasize());
                tempList.add("23个区(市)县、市卫健委、市委社治委");
                tabDataList.add(tempList);
            }
            count++;
        }
        //创建表格行数
        result.put("rows",rows);
        //创建表格列数
        result.put("cols",cols);
        //需要合并单元格的坐标
        result.put("verticallyMapList",verticallyMapList);
        //插入表格的格式数据
        result.put("tabDataList",tabDataList);
        return result;
    }
//    public static  List<EpidemicDataConvergence> getEpidemicDataConvergence(String day){
//        log.info("获取某日某市当前疫情概况");
//        EpidemicDataQuery query = new EpidemicDataQuery();
//        query.setToday(day);
//        List<EpidemicDataConvergence> list = sIEpidemicData.getEpidemicDataConvergence(query);
//        return  list;
//    }

    public static  Map<String,Object> getEpidemicDataIssued(String day){
        log.info("防疫数据下发情况");
        Map<String,Object> result = new HashMap<>();
        EpidemicDataQuery query = new EpidemicDataQuery();
        query.setToday(day);
        List<EpidemicDataIssued> list = sIEpidemicData.getEpidemicDataIssued(query);
        int rows = (int)Math.ceil((double)list.size()/2)+1; //表格行数(加上表格头行)
        int cols = 4; //表格列数
        List<Map<String,Integer>> verticallyMapList = new ArrayList<>();//需要合并的行的坐标
        //表格每行数据
        List<List<Object>> tabDataList = new ArrayList<>();
        for (int i = 0; i < list.size(); i = i + 2) {
            if(i == 0){
                //添加表头数据
                List<Object> theadList = new ArrayList<Object>();
                theadList.add("区(市)县");
                theadList.add("下发数量");
                theadList.add("区(市)县");
                theadList.add("下发数量");
                tabDataList.add(theadList);
            }
            if(i<list.size()) {
                List<Object> tempList = new ArrayList<Object>();
                tempList.add(list.get(i).getOrganization());
                tempList.add(list.get(i).getNum());
                if((i+1)<list.size()) {
                    tempList.add(list.get(i + 1).getOrganization());
                    tempList.add(list.get(i + 1).getNum());
                }
                tabDataList.add(tempList);
            }
        }
        //创建表格行数
        result.put("rows",rows);
        //创建表格列数
        result.put("cols",cols);
        //需要合并单元格的坐标
        result.put("verticallyMapList",verticallyMapList);
        //插入表格的格式数据
        result.put("tabDataList",tabDataList);
        return result;

    }
//    public static  List<EpidemicDataIssued> getEpidemicDataIssued(String day){
//        log.info("防疫数据下发情况");
//        EpidemicDataQuery query = new EpidemicDataQuery();
//        query.setToday(day);
//        List<EpidemicDataIssued> list = sIEpidemicData.getEpidemicDataIssued(query);
//        return  list;
//    }

    //向中高风险地区推送短信情况
    public static EpidemicDataSmsPush getEpidemicDataSmsPush(String day) {
        log.info("向中高风险地区推送短信情况");
        EpidemicDataQuery query = new EpidemicDataQuery();
        query.setToday(day);
        EpidemicDataSmsPush result = sIEpidemicData.getEpidemicDataSmsPush(query);
        return  result;
    }

    //“天府健康通”使用情况
    public static EpidemicDataAppUsed getEpidemicDataAppUsed(String day) {
        log.info("“天府健康通”使用情况");
        EpidemicDataQuery query = new EpidemicDataQuery();
        query.setToday(day);
        EpidemicDataAppUsed result = sIEpidemicData.getEpidemicDataAppUsed(query);
        return  result;
    }
    public static void main(String[] args) {
        /*//模板文件地址
        String inputUrl2 = "C:\\Users\\SongBin\\Desktop\\demo\\报告模板-价格.docx";
        //新生产的模板文件
        String outputUrl2 = "C:\\Users\\SongBin\\Desktop\\demo\\test.docx";
        String uid = UUID.randomUUID().toString();
        AutoTestUtil.visitUrl("http://localhost:8080/showChart?uid="+uid);
        String day = Constant.NOWDATE;
        List<PriceData> list =  DailyPriceUtil.getAllDailyPriceData(day);
        Map<String, String> testMap2 = getAllPriceMap(list);
        Map<String ,String> imgMap = new HashMap<>();
        imgMap.put("$img01","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img02","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img03","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img04","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img05","3f956a32-f236-4baa-a8be-f465fa844580");
        WorderToNewWordUtils.changWord(inputUrl2, outputUrl2, testMap2,imgMap);*/
//        List<PriceData> list = getAllDailyPriceData("2020-08-27","粮食");
//        List<PriceTabData> dpt = getDailyPriceTabData("2020-08-27","粮食");
        System.out.println("成功!");
    }
}
package cnki.bdmsjob.base;

import cnki.bdmsjob.config.ChromeDriverConf;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 通过word模板生成新的word工具类
 * @author SongBin on 2019/9/5.
 */

public class WorderToNewWordUtils {

    /**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
     * @param inputUrl 模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap 需要替换的信息集合
     * @param tableList 需要插入的表格信息集合
     * @return 成功返回true,失败返回false
     */
    public static boolean changWord(String inputUrl, String outputUrl,
                                    Map<String, String> textMap, List<String[]> tableList, Map<String ,String> imgMap,Map<String ,Map<String,Object>> tabMap) {

        //模板转换默认成功
        boolean changeFlag = true;
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            WorderToNewWordUtils.changeText(document, textMap,imgMap,tabMap);
            //解析替换表格对象
            WorderToNewWordUtils.changeTable(document, textMap, tableList);

            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();

        } catch (IOException e) {
            e.printStackTrace();
            changeFlag = false;
        }

        return changeFlag;

    }

    /**
     * 根据无表格模板生成新word文档
     * @param inputUrl 模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap 需要替换的信息集合
     * @return 成功返回true,失败返回false
     */
    public static boolean changWord(String inputUrl, String outputUrl,
                                    Map<String, String> textMap, Map<String ,String> imgMap,Map<String ,Map<String,Object>> tabMap) {
        //模板转换默认成功
        boolean changeFlag = true;
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            WorderToNewWordUtils.changeText(document, textMap,imgMap,tabMap);
            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
            changeFlag = false;
        }
        return changeFlag;
    }

    /**
     * 遍历word获取每种农产品需要统计的菜品类型
     * @param inputUrl 模板地址
     * @return
     */
    public static Map<String,String> getClassifyObj(String inputUrl){
        Map<String,String> map = new HashMap<>();
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //获取段落集合
            List<XWPFParagraph> paragraphs = document.getParagraphs();
            int i = 1;
            for (XWPFParagraph paragraph : paragraphs) {
                //判断此段落时候需要进行替换
                String text = paragraph.getText();
                Matcher m = Pattern.compile("(?d)——(.+?))$").matcher(text);
                if (m.find()) {
                    Matcher matcher=Pattern.compile("(?d)((.+?))$").matcher(text);
                    if (matcher.find()){
                        String objstr = matcher.group(1).replace('、',',');
                        map.put("obj0"+i,objstr);
                        i++;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 替换段落文本
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap, Map<String ,String> imgMap, Map<String ,Map<String,Object>> tabMap){
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();

        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            if(checkText(text)){
                List<XWPFRun> runs = paragraph.getRuns();
                XWPFRun run0 = runs.get(0);
                if(text.matches("(?d)^\\$img0[1-5]")){//插入图片
                    for (XWPFRun run : runs) {
                        //替换模板原来位置
                        run.setText("",0);
                    }
                    changeParagraphImg(run0,imgMap.get(text));
                }else if(text.matches("(?d)^\\$table0[1-9]")){//插入表格
                    for (XWPFRun run : runs) {
                        //替换模板原来位置
                        run.setText("",0);
                    }
                    XmlCursor cursor= paragraph.getCTP().newCursor();
                    XWPFTable table = document.insertNewTbl(cursor);
                    ExportWordUtil ew = new ExportWordUtil();
                    ew.insertxTableInfo(table,tabMap.get(text));
                }else{
                    for (XWPFRun run : runs) {
                        //替换模板原来位置
                        run.setText(changeValue(run.text(), textMap),0);
                    }
                }
            }
        }

    }
    /******************处理文本框内容*******************************/
    public static List<String> patternList=new ArrayList();
    //需要处理的节点名称
    static {
        patternList.add("mc:AlternateContent");
        patternList.add("mc:Choice");
        patternList.add("w:drawing");
        patternList.add("wp:anchor");
        patternList.add("a:graphic");
        patternList.add("a:graphicData");
        patternList.add("wps:wsp");
        patternList.add("wps:txbx");
        patternList.add("w:txbxContent");
        patternList.add("w:p");
        patternList.add("w:r");
        patternList.add("w:t");
    }

    public static void changeTextBox( XWPFDocument document,Map<String, String> map) {
        for(XWPFParagraph paragraph:document.getParagraphs())
            for(XmlObject object:paragraph.getCTP().getRArray())
            {
                XmlCursor cursor = object.newCursor();
                eachchild(cursor, 0,map);
            }
    }

    //回朔查找,因为并不是每一个文本框中只有一个可替换的地方
    public static void eachchild(XmlCursor cursor,int start,Map<String, String> map) {

        //预计子节点个数应该是小于10个节点
        for(int i=0;i<10;i++)
        {
            //如果可以移动到子节点i
            if(cursor.toChild(i)) {
                //如果移动到达的子节点正好是按照顺序是需要的节点 则继续前往下一层
                if(cursor.getDomNode().getNodeName().equals(patternList.get(start))) {
                    if(start==patternList.size()-1) {
                        String reString=cursor.getTextValue();
                        for(String e:map.keySet()) {
                            if(reString.contains(e)) {
                                //    执行替换
                                reString=reString.replaceAll(e, map.get(e));
                            }
                        }

                        //bingo  设置替换节点内容
                        cursor.setTextValue(reString);
                    }

                    //继续下一层  遍历
                    eachchild(cursor,start+1,map);
                }else {
                    cursor.toParent();
                }
            }
        }

//  此处很重要,如果命中或者未命中都需要 遍历其他节点
        cursor.toParent();
    }

    /******************处理文本框内容结束*******************************/
    /**
     * 替换段落文本
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap){
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            if(checkText(text)){
                List<XWPFRun> runs = paragraph.getRuns();
                XWPFRun run0 = runs.get(0);
                for (XWPFRun run : runs) {
                    //替换模板原来位置
                    run.setText("",0);
                }
                //替换模板原来位置
                run0.setText(changeValue(text, textMap),0);
            }
        }

    }
    /**
     * 插入图片
     * @param run
     * @param imgGuid
     */
    public static void changeParagraphImg(XWPFRun run, String imgGuid){
        try {
            String basePath =StringUtil.isBlank(ChromeDriverConf.picSavePath)?"D:/imgupload/":ChromeDriverConf.picSavePath;
            String imgFile = basePath + imgGuid +".jpg";
            System.out.println("插入图表图片:" + imgFile);
            FileInputStream is = new FileInputStream(imgFile);
            run.addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(400), Units.toEMU(300)); // 100x100 pixels
            is.close();
            run.setText("",0);
        } catch (Exception e) {
            System.out.println("Error: ========  插入单个图片时出错了:可能是图片路径不存在。不影响主流程");
            e.printStackTrace();
        }
    }

    /**
     * 替换表格对象方法
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     * @param tableList 需要插入的表格信息集合
     */
    public static void changeTable(XWPFDocument document, Map<String, String> textMap,
                                   List<String[]> tableList){
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();
        for (int i = 0; i < tables.size(); i++) {
            //只处理行数大于等于2的表格,且不循环表头
            XWPFTable table = tables.get(i);
            if(table.getRows().size()>1){
                //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                if(checkText(table.getText())){
                    List<XWPFTableRow> rows = table.getRows();
                    //遍历表格,并替换模板
                    eachTable(rows, textMap);
                }
//                else{
////                  System.out.println("插入"+table.getText());
//                    insertTable(table, tableList);
//                }
            }
        }
    }





    /**
     * 遍历表格
     * @param rows 表格行对象
     * @param textMap 需要替换的信息集合
     */
    public static void eachTable(List<XWPFTableRow> rows , Map<String, String> textMap){
        for (XWPFTableRow row : rows) {
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                //判断单元格是否需要替换
                if(checkText(cell.getText())){
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
                            run.setText(changeValue(run.toString(), textMap),0);
                        }
                    }
                }
            }
        }
    }

    /**
     * 为表格插入数据,行数不够添加新行
     * @param table 需要插入数据的表格
     * @param tableList 插入数据集合
     */
    public static void insertTable(XWPFTable table, List<String[]> tableList){
        //创建行,根据需要插入的数据添加新行,不处理表头
        for(int i = 1; i < tableList.size(); i++){
            XWPFTableRow row =table.createRow();
        }
        //遍历表格插入数据
        List<XWPFTableRow> rows = table.getRows();
        for(int i = 1; i < rows.size(); i++){
            XWPFTableRow newRow = table.getRow(i);
            List<XWPFTableCell> cells = newRow.getTableCells();
            for(int j = 0; j < cells.size(); j++){
                XWPFTableCell cell = cells.get(j);
                cell.setText(tableList.get(i-1)[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 String changeValue(String value, Map<String, String> textMap){
        Set<Entry<String, String>> textSets = textMap.entrySet();
        for (Entry<String, String> textSet : textSets) {
            //匹配模板与替换值 格式${key}
            String key = "${"+textSet.getKey()+"}";
            String regexstr = "(?d)\\$\\{"+textSet.getKey()+"\\}";
            if(value.indexOf(key)!= -1){
                value = value.replaceAll(regexstr,textSet.getValue());
            }
        }
        //模板未匹配到区域替换为空
        if(checkText(value)){
            value = value.replaceAll("(?d)\\$\\{(.+?)\\}","");
        }
        return value;
    }




    public static void main(String[] args) {
//        测试1
        //模板文件地址
        /*String inputUrl = "C:\\Users\\SongBin\\Desktop\\demo\\001.docx";
        //新生产的模板文件
        String outputUrl = "C:\\Users\\SongBin\\Desktop\\demo\\test.docx";

        Map<String, String> testMap = new HashMap<String, String>();
        testMap.put("name", "小明");
        testMap.put("sex", "男");
        testMap.put("age", "30");
        testMap.put("like", "IT");
        testMap.put("birthday", "2019-02-18");
        testMap.put("address", "软件园");
        testMap.put("phone", "18612100611");
        testMap.put("email", "1370811553@qq.com");

        List<String[]> testList = new ArrayList<String[]>();
        testList.add(new String[]{"1","1AA","1BB","1CC"});
        testList.add(new String[]{"2","2AA","2BB","2CC"});
        testList.add(new String[]{"3","3AA","3BB","3CC"});
        testList.add(new String[]{"4","4AA","4BB","4CC"});

        WorderToNewWordUtils.changWord(inputUrl, outputUrl, testMap, testList);*/



//        测试2
        //模板文件地址
        String inputUrl2 = "C:\\Users\\SongBin\\Desktop\\demo\\报告模板-价格.docx";
        //新生产的模板文件
        String outputUrl2 = "C:\\Users\\SongBin\\Desktop\\demo\\test.docx";

        Map<String, String> testMap2 = new HashMap<String, String>();
        testMap2.put("datetime", "2019-02-06");
        testMap2.put("粳米(普通)","粳米(普通)25元/公斤;");
        testMap2.put("大米","大米25元/公斤;");
        testMap2.put("week","07.16-7-22 ");
        Map<String ,String> imgMap = new HashMap<>();
        imgMap.put("$img01","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img02","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img03","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img04","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img05","3f956a32-f236-4baa-a8be-f465fa844580");
        WorderToNewWordUtils.changWord(inputUrl2, outputUrl2, testMap2,imgMap,null);

        String content = "在一些字里面放进去高中这两个字";

        Matcher matcher = Pattern.compile("高中").matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(1));
        }
        //判断此段落时候需要进行替换
        /*String text = "近一周09.05-09.11农产品价格走势图——蔬菜(大白菜、小白菜、油菜、白萝卜、西红柿、黄瓜、茄子、香菇、平菇)";
        Matcher m = Pattern.compile("(?d)——(.+?))$").matcher(text);
        if (m.find()) {
            Matcher matcher=Pattern.compile("(?d)((.+?))$").matcher(text);
            if (matcher.find()){
                String objstr = matcher.group(1).replace('、',',');
                System.out.println(objstr);
            }
        }*/

        //测试但斜杠转转双斜杠
        //模板文件地址
        /*String inputUrl = null;
        try {
            inputUrl = ResourceUtils.getURL("classpath:static/wordmodel/报告模板-价格.docx").getPath().substring(1);
            inputUrl = inputUrl.replaceAll("/", "\\\\\\\\");
            try {
                inputUrl = java.net.URLDecoder.decode(inputUrl,"utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            System.out.println(inputUrl);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }*/
    }
}

 

 

更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: