一、使用情景
以模板为基础,模板中可以包括poi操作比较困难的内容,比如有文本框布局的报告头,页眉页脚等。然后,用poi替换模板中的相关信息,包括表格,段落,文本框中的变量,比如期刊号,日期等。用Poi写入表格,带合并单元格的,段落,图片。
二、通过word模板生成新的word工具类
package cnki.jxjob.base;
import cnki.jxjob.config.ChromeDriverConf;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import javax.xml.namespace.QName;
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) {
//模板转换默认成功
boolean changeFlag = true;
try {
//获取docx解析对象
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
//解析替换文本段落对象
WorderToNewWordUtils.changeText(document, textMap,imgMap);
//解析替换表格对象
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) {
//模板转换默认成功
boolean changeFlag = true;
try {
//获取docx解析对象
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
//解析替换文本段落对象
WorderToNewWordUtils.changeText(document, textMap,imgMap);
//生成新的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){
//获取段落集合
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.indexOf(":")!= -1&&runs.size()>1){
run0.setText(text.substring(0,text.indexOf(":")+1),0);
XWPFRun run1 = runs.get(1);
for (int i=1;i<runs.size();i++) {
//替换模板原来位置
XWPFRun run = runs.get(i);
run.setText("",0);
}
text = text.replaceAll("(?d)^(.+?):","");
//替换模板原来位置
run1.setText(changeValue(text, textMap),0);
run1.setBold(false);
}else{
for (XWPFRun run : runs) {
//替换模板原来位置
run.setText("",0);
}
//替换模板原来位置
run0.setText(changeValue(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)\\$\\{(.+?)\\}","");
}
value = value.replaceAll("(以上所列全部类目)","");
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);
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();
}*/
}
}
三、写入Word工具类
/**
* @author SongBin on 2020/9/3.
*/
package cnki.jxjob.base;
import java.io.*;
import java.math.BigInteger;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import cnki.jxjob.entity.ParagraphStyle;
import cnki.jxjob.entity.TextStyle;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TextAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.poi.xwpf.usermodel.XWPFRelation;
import org.apache.poi.xwpf.usermodel.XWPFRun;
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.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
/**
* @Description 设置docx文档的样式及一些操作
* 2020年09月03日 下午4:20:05
* @Author SongBin
* 基本概念说明:XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档
* XWPFParagraph代表文档、表格、标题等种的段落,由多个XWPFRun组成
* XWPFRun代表具有同样风格的一段文本
* XWPFTable代表一个表格
* XWPFTableRow代表表格的一行
* XWPFTableCell代表表格的一个单元格
* XWPFChar 表示.docx文件中的图表
* XWPFHyperlink 表示超链接
* XWPFPicture 代表图片
*
* 注意:直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun。
*/
public class XWPFHelper {
private static Logger logger = Logger.getLogger(XWPFHelper.class.toString());
/**
* 在模板基础上创建一个word对象
* @return
* @Author Huangxiaocong 2018年12月1日 上午11:56:35
*/
public XWPFDocument createDocumentLikeModel(String inputUrl) {
//模板转换默认成功
XWPFDocument document = null;
try {
//获取docx解析对象
document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
} catch (IOException e) {
e.printStackTrace();
}
return document;
}
/**
* 创建一个word对象
* @return
* @Author Huangxiaocong 2018年12月1日 上午11:56:35
*/
public XWPFDocument createDocument() {
XWPFDocument document = new XWPFDocument();
return document;
}
/**
* 打开word文档
* @param path 文档所在路径
* @return
* @throws IOException
* @Author Huangxiaocong 2018年12月1日 下午12:30:07
*/
public XWPFDocument openDoc(String path) throws IOException {
InputStream is = new FileInputStream(path);
return new XWPFDocument(is);
}
/**
* 保存word文档
* @param document 文档对象
* @param savePath 保存路径
* @throws IOException
* @Author Huangxiaocong 2018年12月1日 下午12:32:37
*/
public void saveDocument(XWPFDocument document, String savePath) throws IOException {
OutputStream os = new FileOutputStream(savePath);
document.write(os);
os.close();
}
/**
* 设置段落文本样式 设置超链接及样式
* @param paragraph
* @param textStyle
* @param url
* @Author Huangxiaocong 2018年12月1日 下午3:56:32
*/
public void addParagraphTextHyperlink(XWPFParagraph paragraph, TextStyle textStyle) {
String id = paragraph.getDocument().getPackagePart().
addExternalRelationship(textStyle.getUrl(),
XWPFRelation.HYPERLINK.getRelation()).getId();
//追加链接并将其绑定到关系中
CTHyperlink cLink = paragraph.getCTP().addNewHyperlink();
cLink.setId(id);
//创建链接文本
CTText ctText = CTText.Factory.newInstance();
ctText.setStringValue(textStyle.getText());
CTR ctr = CTR.Factory.newInstance();
CTRPr rpr = ctr.addNewRPr();
//以下设置各种样式 详情看TextStyle类
if(textStyle.getFontFamily() != "" && textStyle.getFontFamily() != null ) {
CTFonts fonts = rpr.isSetRFonts() ? rpr.getRFonts() : rpr.addNewRFonts();
fonts.setAscii(textStyle.getFontFamily());
//...
}
//设置字体大小
}
/**
* 设置段落的基本样式 设置段落间距信息, 一行 = 100 一磅=20
* @param paragraph
* @param paragStyle
* @Author Huangxiaocong 2018年12月1日 下午4:27:17
*/
public void setParagraphSpacingInfo(XWPFParagraph paragraph, ParagraphStyle paragStyle, STLineSpacingRule.Enum lineValue) {
CTPPr pPPr = getParagraphCTPPr(paragraph);
CTSpacing pSpacing = pPPr.getSpacing() != null ? pPPr.getSpacing() : pPPr.addNewSpacing();
if(paragStyle.isSpace()) {
//段前磅数
if(paragStyle.getBefore() != null) {
pSpacing.setBefore(new BigInteger(paragStyle.getBefore()));
}
//段后磅数
if(paragStyle.getAfter() != null) {
pSpacing.setAfter(new BigInteger(paragStyle.getAfter()));
}
//依次设置段前行数、段后行数
//...
}
//间距
if(paragStyle.isLine()) {
if(paragStyle.getLine() != null) {
pSpacing.setLine(new BigInteger(paragStyle.getLine()));
}
if(lineValue != null) {
pSpacing.setLineRule(lineValue); //
}
}
}
/**
* 设置段落缩进信息 1厘米 约等于 567
* @param paragraph
* @param paragStyle
* @Author Huangxiaocong 2018年12月1日 下午7:59:35
*/
public void setParagraphIndInfo(XWPFParagraph paragraph, ParagraphStyle paragStyle) {
CTPPr pPPr = getParagraphCTPPr(paragraph);
CTInd pInd = pPPr.getInd() != null ? pPPr.getInd() : pPPr.addNewInd();
if(paragStyle.getFirstLine() != null) {
pInd.setFirstLine(new BigInteger(paragStyle.getFirstLine()));
}
//再进行其他设置
//...
}
/**
* 设置段落对齐 方式
* @param paragraph
* @param pAlign
* @param valign
* @Author Huangxiaocong 2018年12月1日 下午8:54:43
*/
public void setParagraphAlignInfo(XWPFParagraph paragraph, ParagraphAlignment pAlign, TextAlignment valign) {
if(pAlign != null) {
paragraph.setAlignment(pAlign);
}
if(valign != null) {
paragraph.setVerticalAlignment(valign);
}
}
/**
* 得到段落的CTPPr
* @param paragraph
* @return
* @Author Huangxiaocong 2018年12月1日 下午7:36:10
*/
public CTPPr getParagraphCTPPr(XWPFParagraph paragraph) {
CTPPr pPPr = null;
if(paragraph.getCTP() != null) {
if(paragraph.getCTP().getPPr() != null) {
pPPr = paragraph.getCTP().getPPr();
} else {
pPPr = paragraph.getCTP().addNewPPr();
}
}
return pPPr;
}
/**
* 得到XWPFRun的CTRPr
* @param paragraph
* @param pRun
* @return
* @Author Huangxiaocong 2018年12月1日 下午7:46:01
*/
public CTRPr getRunCTRPr(XWPFParagraph paragraph, XWPFRun pRun) {
CTRPr ctrPr = null;
if(pRun.getCTR() != null) {
ctrPr = pRun.getCTR().getRPr();
if(ctrPr == null) {
ctrPr = pRun.getCTR().addNewRPr();
}
} else {
ctrPr = paragraph.getCTP().addNewR().addNewRPr();
}
return ctrPr;
}
/**
* 复制表格
* @param targetTable
* @param sourceTable
* @Author Huangxiaocong 2018年12月1日 下午1:40:01
*/
public void copyTable(XWPFTable targetTable, XWPFTable sourceTable) {
//复制表格属性
targetTable.getCTTbl().setTblPr(sourceTable.getCTTbl().getTblPr());
//复制行
for(int i = 0; i < sourceTable.getRows().size(); i++) {
XWPFTableRow targetRow = targetTable.getRow(i);
XWPFTableRow sourceRow = sourceTable.getRow(i);
if(targetRow == null) {
targetTable.addRow(sourceRow);
} else {
copyTableRow(targetRow, sourceRow);
}
}
}
/**
* 复制单元格
* @param targetRow
* @param sourceRow
* @Author Huangxiaocong 2018年12月1日 下午1:33:22
*/
public void copyTableRow(XWPFTableRow targetRow, XWPFTableRow sourceRow) {
//复制样式
if(sourceRow != null) {
targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
}
//复制单元格
for(int i = 0; i < sourceRow.getTableCells().size(); i++) {
XWPFTableCell tCell = targetRow.getCell(i);
XWPFTableCell sCell = sourceRow.getCell(i);
if(tCell == sCell) {
tCell = targetRow.addNewTableCell();
}
copyTableCell(tCell, sCell);
}
}
/**
* 复制单元格(列) 从sourceCell到targetCell
* @param targetCell
* @param sourceCell
* @Author Huangxiaocong 2018年12月1日 下午1:27:38
*/
public void copyTableCell(XWPFTableCell targetCell, XWPFTableCell sourceCell) {
//表格属性
if(sourceCell.getCTTc() != null) {
targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
}
//删除段落
for(int pos = 0; pos < targetCell.getParagraphs().size(); pos++) {
targetCell.removeParagraph(pos);
}
//添加段落
for(XWPFParagraph sourceParag : sourceCell.getParagraphs()) {
XWPFParagraph targetParag = targetCell.addParagraph();
copyParagraph(targetParag, sourceParag);
}
}
/**
* 复制段落,从sourceParag到targetParag
* @param targetParag
* @param sourceParag
* @Author Huangxiaocong 2018年12月1日 下午1:16:26
*/
public void copyParagraph(XWPFParagraph targetParag, XWPFParagraph sourceParag) {
targetParag.getCTP().setPPr(sourceParag.getCTP().getPPr()); //设置段落样式
//移除所有的run
for(int pos = targetParag.getRuns().size() - 1; pos >= 0; pos-- ) {
targetParag.removeRun(pos);
}
//copy新的run
for(XWPFRun sRun : sourceParag.getRuns()) {
XWPFRun tarRun = targetParag.createRun();
copyRun(tarRun, sRun);
}
}
/**
* 复制XWPFRun 从sourceRun到targetRun
* @param targetRun
* @param sourceRun
* @Author Huangxiaocong 2018年12月1日 下午12:56:53
*/
public void copyRun(XWPFRun targetRun, XWPFRun sourceRun) {
//设置targetRun属性
targetRun.getCTR().setRPr(sourceRun.getCTR().getRPr());
targetRun.setText(sourceRun.text());//设置文本
//处理图片
List<XWPFPicture> pictures = sourceRun.getEmbeddedPictures();
for(XWPFPicture picture : pictures) {
try {
copyPicture(targetRun, picture);
} catch (InvalidFormatException e) {
e.printStackTrace();
logger.log(Level.WARNING, "copyRun", e);
} catch (IOException e) {
e.printStackTrace();
logger.log(Level.WARNING, "copyRun", e);
}
}
}
/**
* 复制图片从sourcePicture到 targetRun(XWPFPicture --> XWPFRun)
* @param targetRun
* @param source
* @throws IOException
* @throws InvalidFormatException
* @Author Huangxiaocong 2018年12月1日 下午12:57:33
*/
public void copyPicture(XWPFRun targetRun, XWPFPicture sourcePicture) throws InvalidFormatException, IOException {
XWPFPictureData picData = sourcePicture.getPictureData();
String fileName = picData.getFileName(); //图片的名称
InputStream picInIsData = new ByteArrayInputStream(picData.getData());
int picType = picData.getPictureType();
int width = (int) sourcePicture.getCTPicture().getSpPr().getXfrm().getExt().getCx();
int height = (int) sourcePicture.getCTPicture().getSpPr().getXfrm().getExt().getCy();
targetRun.addPicture(picInIsData, picType, fileName, width, height);
// targetRun.addBreak();//分行
}
}
四、Word中表格操作工具类
/**
* @author SongBin on 2020/9/3.
*/
package cnki.jxjob.base;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.xwpf.usermodel.BodyElementType;
import org.apache.poi.xwpf.usermodel.IBodyElement;
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.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
/**
* @Description 操作word的基本工具类
* 2020年09月03日 下午4:20:05
* @Author SongBin
*/
public class XWPFHelperTable {
/**
* 删除指定位置的表格,被删除表格后的索引位置
* @param document
* @param pos
* @Author Huangxiaocong 2018年12月1日 下午10:32:43
*/
public void deleteTableByIndex(XWPFDocument document, int pos) {
Iterator<IBodyElement> bodyElement = document.getBodyElementsIterator();
int eIndex = 0, tableIndex = -1;
while(bodyElement.hasNext()) {
IBodyElement element = bodyElement.next();
BodyElementType elementType = element.getElementType();
if(elementType == BodyElementType.TABLE) {
tableIndex++;
if(tableIndex == pos) {
break;
}
}
eIndex++;
}
document.removeBodyElement(eIndex);
}
/**
* 获得指定位置的表格
* @param document
* @param index
* @return
* @Author Huangxiaocong 2018年12月1日 下午10:34:14
*/
public XWPFTable getTableByIndex(XWPFDocument document, int index) {
List<XWPFTable> tableList = document.getTables();
if(tableList == null || index < 0 || index > tableList.size()) {
return null;
}
return tableList.get(index);
}
/**
* 得到表格的内容(第一次跨行单元格视为一个,第二次跳过跨行合并的单元格)
* @param table
* @return
* @Author Huangxiaocong 2018年12月1日 下午10:46:41
*/
public List<List<String>> getTableRConten(XWPFTable table) {
List<List<String>> tableContextList = new ArrayList<List<String>>();
for(int rowIndex = 0, rowLen = table.getNumberOfRows(); rowIndex < rowLen; rowIndex++) {
XWPFTableRow row = table.getRow(rowIndex);
List<String> cellContentList = new ArrayList<String>();
for(int colIndex = 0, colLen = row.getTableCells().size(); colIndex < colLen; colIndex++ ) {
XWPFTableCell cell = row.getCell(colIndex);
CTTc ctTc = cell.getCTTc();
if(ctTc.isSetTcPr()) {
CTTcPr tcPr = ctTc.getTcPr();
if(tcPr.isSetHMerge()) {
CTHMerge hMerge = tcPr.getHMerge();
if(STMerge.RESTART.equals(hMerge.getVal())) {
cellContentList.add(getTableCellContent(cell));
}
} else if(tcPr.isSetVMerge()) {
CTVMerge vMerge = tcPr.getVMerge();
if(STMerge.RESTART.equals(vMerge.getVal())) {
cellContentList.add(getTableCellContent(cell));
}
} else {
cellContentList.add(getTableCellContent(cell));
}
}
}
tableContextList.add(cellContentList);
}
return tableContextList;
}
/**
* 获得一个表格的单元格的内容
* @param cell
* @return
* @Author Huangxiaocong 2018年12月2日 下午7:39:23
*/
public String getTableCellContent(XWPFTableCell cell) {
StringBuffer sb = new StringBuffer();
List<XWPFParagraph> cellParagList = cell.getParagraphs();
if(cellParagList != null && cellParagList.size() > 0) {
for(XWPFParagraph xwpfPr: cellParagList) {
List<XWPFRun> runs = xwpfPr.getRuns();
if(runs != null && runs.size() > 0) {
for(XWPFRun xwpfRun : runs) {
sb.append(xwpfRun.getText(0));
}
}
}
}
return sb.toString();
}
/**
* 得到表格内容,合并后的单元格视为一个单元格
* @param table
* @return
* @Author Huangxiaocong 2018年12月2日 下午7:47:19
*/
public List<List<String>> getTableContent(XWPFTable table) {
List<List<String>> tableContentList = new ArrayList<List<String>>();
for (int rowIndex = 0, rowLen = table.getNumberOfRows(); rowIndex < rowLen; rowIndex++) {
XWPFTableRow row = table.getRow(rowIndex);
List<String> cellContentList = new ArrayList<String>();
for (int colIndex = 0, colLen = row.getTableCells().size(); colIndex < colLen; colIndex++) {
XWPFTableCell cell = row.getCell(colIndex);
cellContentList.add(getTableCellContent(cell));
}
tableContentList.add(cellContentList);
}
return tableContentList;
}
/**
* 跨列合并
* @param table
* @param row 所合并的行
* @param fromCell 起始列
* @param toCell 终止列
* @Description
* @Author Huangxiaocong 2018年11月26日 下午9:23:22
*/
public 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) {
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
} else {
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
}
}
}
/**
* 跨行合并
* @param table
* @param col 合并的列
* @param fromRow 起始行
* @param toRow 终止行
* @Description
* @Author Huangxiaocong 2018年11月26日 下午9:09:19
*/
public void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
System.out.println(col+"####"+fromRow+"############"+toRow);
for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
if (table!=null){
System.out.println(rowIndex+"####"+col);
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
//第一个合并单元格用重启合并值设置
if(rowIndex == fromRow) {
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
} else {
//合并第一个单元格的单元被设置为“继续”
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
}
}else {
System.out.println("失败!");
}
}
}
/**
* @Description: 创建表格,创建后表格至少有1行1列,设置列宽
*/
public XWPFTable createTable(XWPFDocument xdoc, int rowSize, int cellSize,
boolean isSetColWidth, int[] colWidths) {
XWPFTable table = xdoc.createTable(rowSize, cellSize);
if (isSetColWidth) {
CTTbl ttbl = table.getCTTbl();
CTTblGrid tblGrid = ttbl.addNewTblGrid();
for (int j = 0, len = Math.min(cellSize, colWidths.length); j < len; j++) {
CTTblGridCol gridCol = tblGrid.addNewGridCol();
gridCol.setW(new BigInteger(String.valueOf(colWidths[j])));
}
}
return table;
}
/**
* @Description: 设置表格总宽度与水平对齐方式
*/
public void setTableWidthAndHAlign(XWPFTable table, String width,
STJc.Enum enumValue) {
CTTblPr tblPr = getTableCTTblPr(table);
// 表格宽度
CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
if (enumValue != null) {
CTJc cTJc = tblPr.addNewJc();
cTJc.setVal(enumValue);
}
// 设置宽度
tblWidth.setW(new BigInteger(width));
tblWidth.setType(STTblWidth.DXA);
}
/**
* @Description: 得到Table的CTTblPr,不存在则新建
*/
public CTTblPr getTableCTTblPr(XWPFTable table) {
CTTbl ttbl = table.getCTTbl();
// 表格属性
CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
return tblPr;
}
/**
* 设置表格行高
* @param infoTable
* @param heigth 高度
* @param vertical 表格内容的显示方式:居中、靠右...
* @Author Huangxiaocong 2018年12月16日
*/
public void setTableHeight(XWPFTable infoTable, int heigth, STVerticalJc.Enum vertical) {
List<XWPFTableRow> rows = infoTable.getRows();
for(XWPFTableRow row : rows) {
CTTrPr trPr = row.getCtRow().addNewTrPr();
CTHeight ht = trPr.addNewTrHeight();
ht.setVal(BigInteger.valueOf(heigth));
List<XWPFTableCell> cells = row.getTableCells();
for(XWPFTableCell tableCell : cells ) {
CTTcPr cttcpr = tableCell.getCTTc().addNewTcPr();
cttcpr.addNewVAlign().setVal(vertical);
}
}
}
}
五、报告导出工具类
/**
* @author SongBin on 2020/9/3.
*/
package cnki.jxjob.base;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import cnki.jxjob.config.ChromeDriverConf;
import cnki.jxjob.entity.PriceData;
import cnki.jxjob.entity.PriceTabData;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
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.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
import org.springframework.util.ResourceUtils;
/**
* @Description 导出word文档
* @Author Huangxiaocong
* 2018年12月1日 下午12:12:15
*/
public class ExportWordUtil {
private XWPFHelperTable xwpfHelperTable = null;
private XWPFHelper xwpfHelper = null;
public ExportWordUtil() {
xwpfHelperTable = new XWPFHelperTable();
xwpfHelper = new XWPFHelper();
}
/**
* 创建好文档的基本 标题,表格 段落等部分
* @param inputUrl 报告模板地址
* @return
* @Author Huangxiaocong 2018年12月16日
*/
public XWPFDocument createXWPFDocument(String inputUrl) {
XWPFDocument doc = xwpfHelper.createDocumentLikeModel(inputUrl);
return doc;
}
/**
* 创建表格的标题样式
* @param document
* @Author Huangxiaocong 2018年12月16日 下午5:28:38
*/
public void createTitleParagraph(XWPFDocument document) {
XWPFParagraph titleParagraph = document.createParagraph(); //新建一个标题段落对象(就是一段文字)
titleParagraph.setAlignment(ParagraphAlignment.CENTER);//样式居中
XWPFRun titleFun = titleParagraph.createRun(); //创建文本对象
// titleFun.setText(titleName); //设置标题的名字
titleFun.setBold(true); //加粗
titleFun.setColor("000000");//设置颜色
titleFun.setFontSize(25); //字体大小
// titleFun.setFontFamily("");//设置字体
//...
titleFun.addBreak(); //换行
}
/**
* 创建章节标题
* @param document
* @Author Huangxiaocong 2018年12月16日 下午5:28:38
*/
public void createSectionTitle(XWPFDocument document,String titleName) {
XWPFParagraph titleParagraph = document.createParagraph(); //新建一个标题段落对象(就是一段文字)
titleParagraph.setAlignment(ParagraphAlignment.LEFT);//样式居中
XWPFRun titleFun = titleParagraph.createRun(); //创建文本对象
titleFun.setText(titleName); //设置标题的名字
titleFun.setBold(true); //加粗
titleFun.setColor("000000");//设置颜色
titleFun.setFontSize(12); //字体大小
titleFun.setFontFamily("宋体");//设置字体
titleFun.addBreak(); //换行
}
/**
* 创建章节简介
* @param document
* @Author Huangxiaocong 2018年12月16日 下午5:28:38
*/
public void createContent(XWPFDocument document,String content) {
XWPFParagraph paragraph = document.createParagraph(); //新建一个标题段落对象(就是一段文字)
XWPFRun sectionContentFun = paragraph.createRun(); //创建文本对象
sectionContentFun.setText(content); //设置标题的名字
sectionContentFun.setColor("000000");//设置颜色
sectionContentFun.setFontSize(10); //字体大小
sectionContentFun.setFontFamily("宋体");//设置字体
}
/**
* 创建章节简介
* @param document
* @Author Huangxiaocong 2018年12月16日 下午5:28:38
*/
public void createSection(XWPFDocument document,String sectionAbstract,String sectionContent) {
XWPFParagraph paragraph = document.createParagraph(); //新建一个标题段落对象(就是一段文字)
paragraph.setIndentationFirstLine(400);//首行缩进
paragraph.setAlignment(ParagraphAlignment.LEFT);//样式居中
XWPFRun sectionAbstractFun = paragraph.createRun(); //创建文本对象
sectionAbstractFun.setText(sectionAbstract); //设置标题的名字
sectionAbstractFun.setBold(true); //加粗
sectionAbstractFun.setColor("000000");//设置颜色
sectionAbstractFun.setFontSize(10); //字体大小
sectionAbstractFun.setFontFamily("宋体");//设置字体
XWPFRun sectionContentFun = paragraph.createRun(); //创建文本对象
sectionContentFun.setText(sectionContent); //设置标题的名字
sectionContentFun.setColor("000000");//设置颜色
sectionContentFun.setFontSize(10); //字体大小
sectionContentFun.setFontFamily("宋体");//设置字体
}
/**
* 设置表格
* @param document
* @param rows
* @param cols
* @Author Huangxiaocong 2018年12月16日
*/
public XWPFTable createTableParagraph(XWPFDocument document, int rows, int cols,List<Map<String,Integer>> verticallyMapList) {
XWPFTable infoTable = document.createTable(rows, cols);
xwpfHelperTable.setTableWidthAndHAlign(infoTable, "9072", STJc.CENTER);
//合并表格
if(verticallyMapList!=null&&verticallyMapList.size()>0){
for(Map<String,Integer> map: verticallyMapList){
System.out.println("表格容量####"+rows+"############"+cols);
xwpfHelperTable.mergeCellsVertically(infoTable, map.get("col"), map.get("fromRow"), map.get("toRow"));
}
}
//设置表格样式
List<XWPFTableRow> rowList = infoTable.getRows();
for(int i = 0; i < rowList.size(); i++) {
XWPFTableRow infoTableRow = rowList.get(i);
List<XWPFTableCell> cellList = infoTableRow.getTableCells();
for(int j = 0; j < cellList.size(); j++) {
XWPFParagraph cellParagraph = cellList.get(j).getParagraphArray(0);
cellParagraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun cellParagraphRun = cellParagraph.createRun();
cellParagraphRun.setFontSize(10);
// if(i % 2 != 0) {
if(i == 0) {
cellParagraphRun.setBold(true);
}
}
}
xwpfHelperTable.setTableHeight(infoTable, 560, STVerticalJc.CENTER);
return infoTable;
}
/**
* 往表格中填充数据
* @param dataList
* @param document
* @throws IOException
* @Author Huangxiaocong 2018年12月16日
*/
@SuppressWarnings("unchecked")
public void exportCheckWord(List<List<Object>> dataList, XWPFDocument document, int pos) throws IOException {
List<List<Object>> tableData = dataList;
XWPFTable table = document.getTableArray(pos);
fillTableData(table, tableData);
// xwpfHelper.saveDocument(document, savePath);
}
/**
* 往表格中填充数据
* @param table
* @param tableData
* @Author Huangxiaocong 2018年12月16日
*/
public void fillTableData(XWPFTable table, List<List<Object>> tableData) {
List<XWPFTableRow> rowList = table.getRows();
for(int i = 0; i < tableData.size(); i++) {
List<Object> list = tableData.get(i);
List<XWPFTableCell> cellList = rowList.get(i).getTableCells();
for(int j = 0; j < list.size(); j++) {
XWPFParagraph cellParagraph = cellList.get(j).getParagraphArray(0);
XWPFRun cellParagraphRun = cellParagraph.getRuns().get(0);
cellParagraphRun.setText(String.valueOf(list.get(j)));
}
}
}
/**
* 插入图片
* @param document
* @param imgGuid
*/
public static void inseartParagraphImg(XWPFDocument document, String imgGuid){
try {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
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();
}
}
/**
* 保存word文档
* @param document 文档对象
* @param savePath 保存路径
* @throws IOException
* @Author Huangxiaocong 2018年12月1日 下午12:32:37
*/
public void saveDocument(XWPFDocument document, String savePath) throws IOException {
xwpfHelper.saveDocument(document,savePath);
}
public static void main(String[] args) throws Exception {
ExportWordUtil ew = new ExportWordUtil();
//模板文件地址
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 = "e:/x.docx";
initWordFile = initWordFile.replaceAll("/", "\\\\\\\\");
initWordFile = java.net.URLDecoder.decode(initWordFile,"utf-8");
String today = Constant.NOWDATE;
XWPFDocument document = ew.createXWPFDocument(initWordFile);
Map<String, String> changeTextBoxMap = new HashMap<String, String>();
changeTextBoxMap.put("datetime", DateUtil.formatZhDate(today));
int periods = DailyPriceUtil.searchPeriods()+1;
changeTextBoxMap.put("periods", String.valueOf(periods));
WorderToNewWordUtils.changeText(document,changeTextBoxMap);
WorderToNewWordUtils.changeTextBox(document,changeTextBoxMap);
ew.saveDocument(document,"e:\\y.docx");
today = "2020-08-27";
List<PriceData> pds = DailyPriceUtil.getDistinctKindNamesByDay(today);
String sectionTitle = "";//章节标题
String[] sectionNum = {"一","二","三","四","五","六","七","八","九","十","十一","十二","十三","十四","十五","十六","十七","十八","十九","二十"};
int currentSection = 0; //当前章节
for(PriceData pd : pds){
String kindName = pd.getKindname();
sectionTitle = sectionNum[currentSection]+"、"+kindName+"价格行情";
/******************************开始加载表格数据***************************************/
List<PriceTabData> ptd = DailyPriceUtil.getDailyPriceTabData(today,kindName);
Map<String,Object> dataAnalyResult = DailyPriceUtil.dataAnalysis(ptd);
//创建表格行数
int rows = Integer.valueOf(dataAnalyResult.get("rows").toString());
//创建表格列数
int cols = Integer.valueOf(dataAnalyResult.get("cols").toString());
//需要合并单元格的坐标
List<Map<String,Integer>> verticallyMapList = (List<Map<String,Integer>>)dataAnalyResult.get("verticallyMapList");
//插入表格的格式数据
List<List<Object>> tabDataList = (List<List<Object>>)dataAnalyResult.get("tabDataList");
//章节简介
String sectionAbstract = dataAnalyResult.get("sectionAbstract").toString();
//章节正文
String sectionContent = dataAnalyResult.get("sectionContent").toString();
//###########################开始写入############################
System.out.println(sectionTitle+"################");
ew.createSectionTitle(document,sectionTitle);//章节标题
ew.createSection(document,sectionAbstract,sectionContent);//章节
XWPFTable infoTable = ew.createTableParagraph(document, rows, cols,verticallyMapList);//创建表格并合并单元格
// int pos = currentSection;
// ew.exportCheckWord(tabDataList, document ,pos);
ew.fillTableData(infoTable,tabDataList);
/******************************表格数据加载完毕***************************************/
/******************************插入图表***************************************/
List<PriceData> prds = DailyPriceUtil.getProductNamesByKindNameToday(today,kindName);
if(prds==null || prds.size()<=0){
prds = DailyPriceUtil.getProductNamesByKindNameToday(DateUtil.getBeforeDay(today),kindName);
}
if(prds==null || prds.size()<=0){
prds = DailyPriceUtil.getProductNamesByKindName(today,kindName);
}
List<String> productNames = prds.stream().map(prd -> "'"+pd.getProductname()+"'").collect(Collectors.toList());
Map<String ,String> imgMap = new HashMap<>();
List<String> parms = new ArrayList<>();
for(int i=1;i<6;i++){
String uid = UUID.randomUUID().toString();
imgMap.put("$img0"+i,uid);
parms.add("uid0"+i+"="+uid);
}
/******************************插入图表结束***************************************/
currentSection ++;
}
String savePath = "E:/expWordTest.docx";
ew.xwpfHelper.saveDocument(document, savePath);
// List<List<Object>> list = new ArrayList<List<Object>>();
//
// List<Object> tempList = new ArrayList<Object>();
// tempList.add("姓名");
// tempList.add("黄xx");
// tempList.add("性别");
// tempList.add("男");
// tempList.add("出生日期");
// tempList.add("2018-10-10");
// list.add(tempList);
// tempList = new ArrayList<Object>();
// tempList.add("身份证号");
// tempList.add("36073xxxxxxxxxxx");
// list.add(tempList);
// tempList = new ArrayList<Object>();
// tempList.add("出生地");
// tempList.add("江西");
// tempList.add("名族");
// tempList.add("汉");
// tempList.add("婚否");
// tempList.add("否");
// list.add(tempList);
// tempList = new ArrayList<Object>();
// tempList.add("既往病史");
// tempList.add("无");
// list.add(tempList);
//
// Map<String, Object> dataList = new HashMap<String, Object>();
// dataList.put("TITLE", "个人体检表");
// dataList.put("TABLEDATA", list);
// ew.exportCheckWord(dataList, document, "E:/expWordTest.docx");
System.out.println("文档生成成功");
}
}
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载