2022/10/21提交

This commit is contained in:
zangshuihua 2022-10-21 08:56:20 +08:00
parent a4e9124c1e
commit cf9644ef29
8 changed files with 13 additions and 1475 deletions

View File

@ -2,7 +2,7 @@ package com.ruoyi.web.controller.shate;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.BarChart;
import com.ruoyi.common.utils.chartForWord.CustomXWPFDocument;
import com.ruoyi.common.utils.CustomXWPFDocument;
import com.ruoyi.common.utils.shate.PageUtils;
import com.ruoyi.system.domain_shate.*;
@ -11,7 +11,6 @@ import com.ruoyi.system.service_shate.IPlantingSuitabilityService;
import com.ruoyi.system.service_shate.ISeedingSuccessService;
import com.ruoyi.system.service_shate.IVegetationHealthServices;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.Document;
@ -560,11 +559,16 @@ public class DateUploadController
//创建第一个段落的内容
BarChart.createParagraphAndInsertWord(docxDocument, "Date time: "+year);
BarChart.createParagraphAndInsertWord(docxDocument, "Evaluation area: "+zone);
//创建第二段落的标题
BarChart.createFirstLevelTopic(docxDocument, "2.Results of remote sensing monitoring of seeding success rate");
//循环判断有多少个资源
List<SeedingSuccessRate> seedingSuccessRates = seedingSuccessService.sqlSeeding(zone, year);
for (SeedingSuccessRate seedingSuccessRate : seedingSuccessRates) {
//图片的url
//String productCode1 = seedingSuccessRate.getProductCode1();
//String productCode2 = seedingSuccessRate.getProductCode2();
//创建第二段落的内容
BarChart.insertPic(docxDocument, "C:\\Users\\xkrs\\Desktop\\pic\\1.png");
BarChart.setPicTitle(docxDocument, "Spatial distribution data of successful seeding regions");
@ -577,7 +581,9 @@ public class DateUploadController
//获取ProductCode1的集合
List<String> M_code=new ArrayList<>();
List<String> H_code=new ArrayList<>();
//查询数据库中有多少条数据
List<VegetationHealth> vegetationHealths = vegetationHealthServices.sqlInfo(zone, year);
//循环查询的数据分别加入到不同的集合中作为中质量和高质量的循环次数
for (VegetationHealth vegetationHealth : vegetationHealths) {
String productCode1 = vegetationHealth.getProductCode1();
if(productCode1.startsWith("M"))
@ -637,6 +643,8 @@ public class DateUploadController
List<PlantingSuitability> plantingSuitabilities = plantingSuitabilityService.sqlSeeding(zone);
for (PlantingSuitability suitability : plantingSuitabilities) {
BarChart.createFirstLevelTopic(docxDocument,"4.Results of remote sensing monitoring of planting suitability");
//获取图片的url
String productCode1 = suitability.getProductCode1();
//第四个标题的内容
BarChart.insertPic(docxDocument,"C:\\Users\\xkrs\\Desktop\\pic\\1.png");
BarChart.setPicTitle(docxDocument,"Spatial distribution data of planting suitability");
@ -647,7 +655,7 @@ public class DateUploadController
Double s3 = suitability.getNotSuitable();
Double[] yAxisData2 = new Double[]{s1, s2, s3};
BarChart.drawTable(docxDocument,xAxisData2,yAxisData2);
BarChart.setPicTitle(docxDocument,"Spatial distribution data of planting suitability");
BarChart.setPicTitle(docxDocument,"Classification statistics of planting suitability");
BarChart.createParagraphAndInsertWord(docxDocument,"In "+suitability.getZone()+" region, the area of very suitable region was "+suitability.getVerySuitable()+" hm², accounting for "+BarChart.getDoubleNumber((suitability.getVerySuitable()/suitability.getTotalArea())*100)+"%. The area of suitable grade was "+suitability.getSuitable()+" hm², accounting for "+BarChart.getDoubleNumber((suitability.getSuitable()/suitability.getTotalArea())*100)+"%. The area of unsuitable area was "+suitability.getNotSuitable()+" hm², accounting for "+BarChart.getDoubleNumber((suitability.getNotSuitable()/suitability.getTotalArea())*100)+"%.");
}
response.setCharacterEncoding("UTF-8");

View File

@ -1,199 +0,0 @@
package com.ruoyi.web.controller.shate;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.utils.chartForWord.CustomXWPFDocument;
import com.ruoyi.common.utils.chartForWord.ExportUtils;
import com.ruoyi.common.utils.chartForWord.PoiChartsTools;
import com.ruoyi.common.utils.chartForWord.PoiWordUtil;
import com.ruoyi.system.service_shate.impl.DateUploadServiceImpl;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 操作word
* @author shuaihua zang
* http://localhost:9080/poi/barCharts
*/
@RestController
public class PoiController {
@GetMapping("/poi/barCharts")
public void barCharts(HttpServletResponse response) {
try (InputStream is = this.getClass().getClassLoader()
.getResourceAsStream("V3.0.docx");
ServletOutputStream out = response.getOutputStream()) {
if (is == null) {
throw new RuntimeException("未找到模板信息");
}
//XWPFDocument doc = new XWPFDocument(is);
CustomXWPFDocument doc = new CustomXWPFDocument(is);
this.doBarCharts(PoiChartsTools.getPOIXMLDocumentPart(doc,
"/word/charts/chart1.xml"));
this.doBarCharts(PoiChartsTools.getPOIXMLDocumentPart(doc,
"/word/charts/chart2.xml"));
this.doBarCharts(PoiChartsTools.getPOIXMLDocumentPart(doc,
"/word/charts/chart3.xml"));
ExportUtils exportUtils=new ExportUtils();
exportUtils.insertImage(doc);
exportUtils.insertText(doc);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/msword");
//response.setContentType("application/octet-stream");
//String filename = "test.docx";
//response.setHeader("Content-disposition", "attachment;filename="
//+ URLEncoder.encode(filename, "UTF-8"));
//doc.write(out);
//out.flush();
String fileName = "Evaluation report of planting monitoring in ITBA Nature Reserve - V3.0.docx";
response.setHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
ServletOutputStream responseOutputStream = response.getOutputStream();
doc.write(responseOutputStream);
responseOutputStream.flush();
responseOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 处理图表数据-柱状图
*/
public void doBarCharts(POIXMLDocumentPart chart1) {
/*// 标题
List<String> titleArr = CollUtil.newArrayList(" ", "Health","Normal","Not-Health");
// 字段名
List<String> fldNameArr = CollUtil.newArrayList("item1", "item2","item3","item4");
// 数据集合
List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
Map<String, String> base1 = new HashMap<>(4);
base1.put("item1", " " );
base1.put("item2", "1000");
base1.put("item3", "700");
base1.put("item4", "1200" );
listItemsByType.add(base1);*/
// 标题
List<String> titleArr = CollUtil.newArrayList(" ", "date");
// 字段名
List<String> fldNameArr = CollUtil.newArrayList("item1", "item2");
// 数据集合
List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
for(int i=0;i<3;i++)
{
if(i==0)
{
Map<String, String> base1 = new HashMap<>(2);
base1.put("item1", "Health" );
base1.put("item2", "100");
listItemsByType.add(base1);
}
if(i==1)
{
Map<String, String> base1 = new HashMap<>(2);
base1.put("item1", "Normal" );
base1.put("item2", "300");
listItemsByType.add(base1);
}
if(i==2)
{
Map<String, String> base1 = new HashMap<>(2);
base1.put("item1", "Not-Health" );
base1.put("item2", "500");
listItemsByType.add(base1);
}
}
PoiChartsTools.replaceBarCharts(chart1, titleArr, fldNameArr, listItemsByType);
}
/**
* 处理图表数据-折线图
*/
private void doLineChart(POIXMLDocumentPart chart) {
// 标题
List<String> titleArr = CollUtil.newArrayList("类别", "系列1", "系列2", "系列3");
// 字段名
List<String> fldNameArr = CollUtil.newArrayList("item1", "item2", "item3", "item4");
// 数据集合
List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
for (int i = 1; i < 5; i++) {
Map<String, String> base1 = new HashMap<>(4);
base1.put("item1", "折线图" + i);
base1.put("item2", "100");
base1.put("item3", "20");
base1.put("item4", "3");
listItemsByType.add(base1);
}
PoiChartsTools.replaceLineCharts(chart, titleArr, fldNameArr, listItemsByType);
}
/**
* 处理图表数据-饼图
*/
private void doPieCharts(POIXMLDocumentPart chart) {
// 标题
List<String> titleArr = CollUtil.newArrayList("类别", "系列1", "系列2", "系列3");
// 字段名
List<String> fldNameArr = CollUtil.newArrayList("item1", "item2", "item3", "item4");
// 数据集合
List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
for (int i = 1; i < 5; i++) {
Map<String, String> base1 = new HashMap<>(4);
base1.put("item1", "饼图" + i);
base1.put("item2", "100");
base1.put("item3", "20");
base1.put("item4", "3");
listItemsByType.add(base1);
}
PoiChartsTools.replacePieCharts(chart, titleArr, fldNameArr, listItemsByType);
}
/**
* 处理表格-新增行
*/
private void insertTable(XWPFTable table) {
List<List<String[]>> tableList = new ArrayList<>();
List<String[]> table1 = new ArrayList<>();
table1.add(new String[]{"1", "张三", "", "22", "186xxxxxxxx"});
table1.add(new String[]{"2", "李四", "", "23", "187xxxxxxxx"});
table1.add(new String[]{"3", "王五", "", "24", "188xxxxxxxx"});
table1.add(new String[]{"4", "赵六", "", "25", "189xxxxxxxx"});
tableList.add(table1);
PoiWordUtil.insertTable(table, table1, 2);
PoiWordUtil.mergeCellsHorizontal(table, 0, 0, 1);
PoiWordUtil.mergeCellsHorizontal(table, 0, 3, 4);
}
/**
* 处理表格-替换表格中信息
*/
private void replaceTable(XWPFTable table) {
Map<String, String> params = new HashMap<>();
params.put("name", "XXXWord");
params.put("start", "2021-04-21");
params.put("end", "2021-04-28");
PoiWordUtil.replaceTableParams(table, params);
}
}

View File

@ -1,11 +1,9 @@
package com.ruoyi.common.utils.chartForWord;
package com.ruoyi.common.utils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.XmlException;

View File

@ -1,209 +0,0 @@
package com.ruoyi.common.utils.chartForWord;
import com.ruoyi.common.utils.StringFilterUtil;
import com.ruoyi.common.utils.chartForWord.CustomXWPFDocument;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.*;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.List;
/**
* @Author shuaihua zang
* @date 2022/10/8
* 导出word的工具类
*/
public class ExportUtils {
/**
* 读取模板
*
* @throws Exception
*/
public void operatorWord(HttpServletResponse response) throws Exception {
//获得模板文件
InputStream docis = new FileInputStream("C:\\Users\\xkrs\\Desktop\\V3.0.docx");
//转成word
CustomXWPFDocument document = new CustomXWPFDocument(docis);
//写入图片
this.insertImage(document);
//段落替换对象
this.insertText(document);
//把doc输出到输出流
response.setCharacterEncoding("UTF-8");
response.setContentType("application/msword");
//文件名
String fileName = "Evaluation report of planting monitoring in ITBA Nature Reserve - V2.0.docx";
response.setHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
ServletOutputStream responseOutputStream = response.getOutputStream();
document.write(responseOutputStream);
responseOutputStream.flush();
responseOutputStream.close();
//in.close();
}
/**
* 写入图片在word中
* @param document
* @throws IOException
* @throws InvalidFormatException
*/
public void insertImage(CustomXWPFDocument document) throws Exception{
//定义一个URL对象
URL url = new URL("https://rs.sensetime.com/sl-temp/thumbs/cc1hsd7ng0b90dum9jcg.png");
//打开连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为10秒
conn.setConnectTimeout(10 * 1000);
InputStream in = conn.getInputStream();
//图片
//FileInputStream in = new FileInputStream("https://rs.sensetime.com/sl-temp/thumbs/cc1hsd7ng0b90dum9jcg.png");
//段落集合
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
//获取到段落中的所有文本内容
String text = paragraph.getText();
//判断此段落中是否有需要进行替换的文本
if (checkText(text)) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
//替换模板原来位置
String key = "${ct_pg2_image_1}";
//if (run.toString().indexOf(key) != -1) {
if (run.text().contains(key)) {
byte[] ba = new byte[in.available()];
int len = in.read(ba);
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(ba, 0, len);
//设置图片
document.addPictureData(byteInputStream, XWPFDocument.PICTURE_TYPE_PNG);
//创建一个word图片并插入到文档中-->像素可改
document.createPicture(document.getAllPictures().size() - 1, 100, 100, paragraph);
}
break;
}
//break;
}
}
in.close();
}
public void insertText (CustomXWPFDocument document){
//声明替换模板对象
Map textMap = new HashMap();
textMap.put("${ct_1}", "11");
textMap.put("${ct_2}", "12");
textMap.put("${ct_3}", "13");
textMap.put("${ct_4}", "14");
textMap.put("${ct_5}", "15");
textMap.put("${ct_6}", "16");
textMap.put("${ct_7}", "17");
textMap.put("${ct_8}", "18");
textMap.put("${ct_9}", "19");
textMap.put("${ct_10}", "20");
textMap.put("${ct_11}", "21");
textMap.put("${ct_12}", "22");
textMap.put("${ct_13}", "23");
textMap.put("${ct_14}", "24");
textMap.put("${ct_1515}", "25");
textMap.put("${ct_16}", "26");
textMap.put("${ct_17}", "27");
textMap.put("${ct_18}", "28");
textMap.put("${ct_19}", "29");
textMap.put("${ct_20}", "30");
textMap.put("${ct_21}", "31");
textMap.put("${ct_22}", "32");
textMap.put("${ct_23}", "33");
textMap.put("${ct_24}", "34");
textMap.put("${ct_25}", "35");
textMap.put("${ct_26}", "36");
textMap.put("${ct_27}", "37");
textMap.put("${ct_28}", "38");
textMap.put("${ct_29}", "39");
//替换模板数据
changeText(document, textMap);
}
/**
* 替换段落文本
*
* @param document docx解析对象
* @param textMap 需要替换的信息集合
*/
public static void changeText (XWPFDocument document, Map < String, Object > textMap){
//获取段落集合
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
//获取到段落中的所有文本内容
String text = paragraph.getText();
//判断此段落中是否有需要进行替换的文本
if (checkText(text)) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
//替换模板原来位置
//System.out.println(run.text());
run.setText(changeText_$(run.text()) + (String) changeValue(run.text().toString(), textMap), 0);
}
}
}
}
/**
* 判断文本中是否包含$
*
* @param text 文本
* @return 包含返回true, 不包含返回false
*/
public static boolean checkText (String text){
boolean check = false;
if (text.indexOf("$") != -1) {
check = true;
}
return check;
}
/**
* 替换模板${}
*/
private static Object changeValue (String value, Map < String, Object > textMap){
Set<Map.Entry<String, Object>> textSets = textMap.entrySet();
Object valu = "";
for (Map.Entry<String, Object> textSet : textSets) {
// 匹配模板与替换值 格式${key}
String key = textSet.getKey();
if (value.contains(key)) {
valu = (String) textSet.getValue();
}
}
return valu;
}
/**
* 替换原先段落中的${}
* @param text
* @return
*/
public static String changeText_$ (String text)
{
if (!text.contains("$")) {
return text;
}
String filterForBetween = StringFilterUtil.filterForBetween(text, '$', '}');
System.out.println(filterForBetween);
return filterForBetween;
}
}

View File

@ -1,110 +0,0 @@
package com.ruoyi.common.utils.chartForWord;
import com.ruoyi.common.utils.BarChart;
import com.ruoyi.common.utils.chartForWord.CustomXWPFDocument;
import org.apache.poi.xwpf.usermodel.*;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 生成动态word
* @author shuaihua zang
* @date 2022/10/13
*/
public class GenerateWord {
public static void makeWord(HttpServletResponse response,HttpServletRequest request,int pg2_size,int pg3_size)throws Exception {
//创建文本对象
CustomXWPFDocument docxDocument = new CustomXWPFDocument();
//secondRun.setColor("FFC0CB");
//secondRun.setUnderline(UnderlinePatterns.SINGLE);
//paragraph_2_title_run.addCarriageReturn();
//paragraphX2.setIndentationFirstLine(420);//首行缩进
//paragraph_2_title.setStyle("2");
//创建标题
BarChart.setTitle(docxDocument,"Evaluation report of planting monitoring in ITBA Nature Reserve");
//创建第一个段落的标题
BarChart.createFirstLevelTopic(docxDocument, "1.Background information");
//创建第一个段落的内容
BarChart.createParagraphAndInsertWord(docxDocument, "Date time:${ct_pg1_1}");
BarChart.createParagraphAndInsertWord(docxDocument, "Evaluation area:${ct_pg1_2}");
//创建第二段落的标题
BarChart.createFirstLevelTopic(docxDocument, "2.Results of remote sensing monitoring of seeding success rate");
//循环判断有多少个资源
for (int i = 0; i < pg2_size; i++) {
//创建第二段落的内容
BarChart.insertPic(docxDocument, "C:\\Users\\xkrs\\Desktop\\pic\\1.png");
BarChart.setPicTitle(docxDocument, "Spatial distribution data of successful seeding regions");
BarChart.insertPic(docxDocument, "C:\\Users\\xkrs\\Desktop\\pic\\2.png");
BarChart.setPicTitle(docxDocument, "Spatial distribution data of seeding success rate");
BarChart.createParagraphAndInsertWord(docxDocument, "${ct_pg2_wz_1}.The total planting area in ${ct_pg2_wz_2} area was ${ct_pg2_wz_3} hm2, the vegetation survival area was ${ct_pg2_wz_4} hm2, and the seeding success rate was ${ct_pg2_wz_5} %.");
}
//第三段的标题
BarChart.createFirstLevelTopic(docxDocument, "3.Results of remote sensing monitoring of vegetation health");
for(int i = 1; i <=pg3_size; i=i+2) {
int j=i+1;
//第三段的内容
//第三段的第一个小标题
BarChart.createSecondLevelTopic(docxDocument, "3."+i+".Monitoring results of medium resolution data");
//第三段的第一个小标题的内容
BarChart.insertPic(docxDocument, "C:\\Users\\xkrs\\Desktop\\pic\\2.png");
BarChart.setPicTitle(docxDocument, "Spatial distribution data of vegetation planting area");
BarChart.insertPic(docxDocument, "C:\\Users\\xkrs\\Desktop\\pic\\1.png");
BarChart.setPicTitle(docxDocument, "Spatial distribution data of vegetation health status");
//插入柱状图表
String[] xAxisData = new String[]{"Health", "Normal", "Not-Health"};
Integer[] yAxisData = new Integer[]{1000, 700, 1200};
//BarChart.drawTable(docxDocument,xAxisData,yAxisData);
BarChart.setPicTitle(docxDocument, "Statistical data on vegetation health");
BarChart.createParagraphAndInsertWord(docxDocument, "2022-06-04.Based on the monitoring results of high resolution satellite images, the area of healthy vegetation growth in 01 region was 1202.8 hm2, accounting for 40.7%. The area with normal vegetation growth was 749.9 hm2, accounting for 25.4%. The area of unhealthy vegetation growth was 1000.2 hm2, accounting for 33.9%.");
//第三段的第二个小标题
BarChart.createSecondLevelTopic(docxDocument, "3."+j+".Monitoring results of high resolution data");
//第三段的第二个小标题的内容
BarChart.insertPic(docxDocument, "C:\\Users\\xkrs\\Desktop\\pic\\1.png");
BarChart.setPicTitle(docxDocument, "Spatial distribution data of vegetation planting area");
BarChart.insertPic(docxDocument, "C:\\Users\\xkrs\\Desktop\\pic\\2.png");
BarChart.setPicTitle(docxDocument, "Spatial distribution data of vegetation health status");
//此处插入图表
String[] xAxisData1 = new String[]{"Health", "Normal", "Not-Health"};
Integer[] yAxisData1 = new Integer[]{1000, 700, 1200};
//BarChart.drawTable(docxDocument,xAxisData1,yAxisData1);
BarChart.setPicTitle(docxDocument, "Statistical data on vegetation health");
BarChart.createParagraphAndInsertWord(docxDocument, "2022-06-04.Based on the monitoring results of high resolution satellite images, the area of healthy vegetation growth in 01 region was 1202.8 hm2, accounting for 40.7%. The area with normal vegetation growth was 749.9 hm2, accounting for 25.4%. The area of unhealthy vegetation growth was 1000.2 hm2, accounting for 33.9%.");
}
//第四个标题
BarChart.createFirstLevelTopic(docxDocument,"4.Results of remote sensing monitoring of planting suitability");
//第四个标题的内容
BarChart.insertPic(docxDocument,"C:\\Users\\xkrs\\Desktop\\pic\\1.png");
BarChart.setPicTitle(docxDocument,"Spatial distribution data of planting suitability");
//此处插入图表
String[] xAxisData2 = new String[]{"Health", "Normal", "Not-Health"};
Integer[] yAxisData2 = new Integer[]{1000, 700, 1200};
//BarChart.drawTable(docxDocument,xAxisData2,yAxisData2);
BarChart.setPicTitle(docxDocument,"Spatial distribution data of planting suitability");
BarChart.createParagraphAndInsertWord(docxDocument,"In 01 region, the area of very suitable region was 1202.8 hm2, accounting for 40.7%. The area of suitable grade was 749.9 hm2, accounting for 25.4%. The area of unsuitable area was 1000.2 hm2, accounting for 33.9%.");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/msword");
//文件名
String fileName = "Evaluation report of planting monitoring in ITBA Nature Reserve - V2.0.docx";
response.setHeader("Content-Disposition","attachment;fileName="+new
String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
ServletOutputStream responseOutputStream = response.getOutputStream();
docxDocument.write(responseOutputStream);
responseOutputStream.flush();
responseOutputStream.close();
}
}

View File

@ -1,651 +0,0 @@
package com.ruoyi.common.utils.chartForWord;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFChart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.openxmlformats.schemas.drawingml.x2006.chart.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* poi操作word中图表的工具类
*
* @author shuaihua zang
* @date 2022/10/10
*/
@Component
public class PoiChartsTools {
private static final BigDecimal bd2 = new BigDecimal("2");
/**
* 获取word模板中的所有图表元素用map存放
*/
public static Map<String, POIXMLDocumentPart> getPOIXMLDocumentPartMap(XWPFDocument doc) {
// 获取word模板中的所有图表元素用map存放
// 为什么不用list保存查看doc.getRelations()的源码可知源码中使用了hashMap读取文档图表元素
// 对relations变量进行打印后发现图表顺序和文档中的顺序不一致也就是说relations的图表顺序不是文档中从上到下的顺序
Map<String, POIXMLDocumentPart> chartsMap = new HashMap<>();
//动态刷新图表
List<POIXMLDocumentPart> relations = doc.getRelations();
for (POIXMLDocumentPart poixmlDocumentPart : relations) {
if (poixmlDocumentPart instanceof XWPFChart) { // 如果是图表元素
String str = poixmlDocumentPart.toString();
String key = str.replaceAll("Name: ", "")
.replaceAll(" - Content Type: application/vnd\\.openxmlformats-officedocument\\.drawingml\\.chart\\+xml", "")
.trim();
chartsMap.put(key, poixmlDocumentPart);
}
}
return chartsMap;
}
/**
* 获取word模板中的对应名称的图表元素
* 返回null则查询不到
*/
public static POIXMLDocumentPart getPOIXMLDocumentPart(XWPFDocument doc, String chartsName) {
List<POIXMLDocumentPart> relations = doc.getRelations();
for (POIXMLDocumentPart poixmlDocumentPart : relations) {
// 如果是图表元素
if (poixmlDocumentPart instanceof XWPFChart) {
String str = poixmlDocumentPart.toString();
String key = str.replaceAll("Name: ", "")
.replaceAll(" - Content Type: application/vnd\\.openxmlformats-officedocument\\.drawingml\\.chart\\+xml", "")
.trim();
if (key.equals(chartsName)){
return poixmlDocumentPart;
}
}
}
return null;
}
/**
* 调用替换柱状图数据
*/
public static void replaceBarCharts(POIXMLDocumentPart poixmlDocumentPart,
List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
XWPFChart chart = (XWPFChart) poixmlDocumentPart;
chart.getCTChart();
//根据属性第一列名称切换数据类型
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTBarChart barChart = plotArea.getBarChartArray(0);
List<CTBarSer> BarSerList = barChart.getSerList(); // 获取柱状图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshBarStrGraphContent(barChart, BarSerList, listItemsByType, fldNameArr, 1);
}
/**
* 调用替换折线图数据
*/
public static void replaceLineCharts(POIXMLDocumentPart poixmlDocumentPart,
List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
XWPFChart chart = (XWPFChart) poixmlDocumentPart;
chart.getCTChart();
//根据属性第一列名称切换数据类型
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTLineChart lineChart = plotArea.getLineChartArray(0);
List<CTLineSer> lineSerList = lineChart.getSerList(); // 获取折线图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, 1);
}
/**
* 调用替换饼图数据
*/
public static void replacePieCharts(POIXMLDocumentPart poixmlDocumentPart,
List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
XWPFChart chart = (XWPFChart) poixmlDocumentPart;
chart.getCTChart();
//根据属性第一列名称切换数据类型
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTPieChart pieChart = plotArea.getPieChartArray(0);
List<CTPieSer> pieSerList = pieChart.getSerList(); // 获取饼图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshPieStrGraphContent(pieChart, pieSerList, listItemsByType, fldNameArr, 1);
}
/**
* 调用替换柱状图折线图组合数据
*/
public static void replaceCombinationCharts(POIXMLDocumentPart poixmlDocumentPart,
List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
XWPFChart chart = (XWPFChart) poixmlDocumentPart;
chart.getCTChart();
//根据属性第一列名称切换数据类型
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTBarChart barChart = plotArea.getBarChartArray(0);
List<CTBarSer> barSerList = barChart.getSerList(); // 获取柱状图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshBarStrGraphContent(barChart, barSerList, listItemsByType, fldNameArr, 1);
CTBarChart barChart2 = plotArea.getBarChartArray(0);
List<CTBarSer> barSerList2 = barChart2.getSerList(); // 获取柱状图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshBarStrGraphContent(barChart2, barSerList2, listItemsByType, fldNameArr, 1);
CTLineChart lineChart = plotArea.getLineChartArray(0);
List<CTLineSer> lineSerList = lineChart.getSerList(); // 获取折线图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, 1);
}
/**
* 刷新折线图数据方法
*
* @param typeChart
* @param serList
* @param dataList
* @param fldNameArr
* @param position
* @return
*/
public static boolean refreshLineStrGraphContent(Object typeChart,
List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, int position) {
boolean result = true;
//更新数据区域
for (int i = 0; i < serList.size(); i++) {
//CTSerTx tx=null;
CTAxDataSource cat = null;
CTNumDataSource val = null;
CTLineSer ser = ((CTLineChart) typeChart).getSerArray(i);
//tx= ser.getTx();
// Category Axis Data
cat = ser.getCat();
// 获取图表的值
val = ser.getVal();
// strData.set
CTStrData strData = cat.getStrRef().getStrCache();
CTNumData numData = val.getNumRef().getNumCache();
strData.setPtArray((CTStrVal[]) null); // unset old axis text
numData.setPtArray((CTNumVal[]) null); // unset old values
// set model
long idx = 0;
for (int j = 0; j < dataList.size(); j++) {
//判断获取的值是否为空
String value = "0";
if (new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))) != null) {
value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();
}
if (!"0".equals(value)) {
CTNumVal numVal = numData.addNewPt();//序列值
numVal.setIdx(idx);
numVal.setV(value);
}
CTStrVal sVal = strData.addNewPt();//序列名称
sVal.setIdx(idx);
sVal.setV(dataList.get(j).get(fldNameArr.get(0)));
idx++;
}
numData.getPtCount().setVal(idx);
strData.getPtCount().setVal(idx);
//赋值横坐标数据区域
String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0)
.formatAsString("Sheet1", false);
cat.getStrRef().setF(axisDataRange);
//数据区域
String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position)
.formatAsString("Sheet1", false);
val.getNumRef().setF(numDataRange);
// 设置系列生成方向
}
return result;
}
/**
* 刷新柱状图数据方法
*
* @param typeChart
* @param serList
* @param dataList
* @param fldNameArr
* @param position
* @return
*/
public static boolean refreshBarStrGraphContent(Object typeChart,
List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, int position) {
boolean result = true;
//更新数据区域
for (int i = 0; i < serList.size(); i++) {
//CTSerTx tx=null;
CTAxDataSource cat = null;
CTNumDataSource val = null;
CTBarSer ser = ((CTBarChart) typeChart).getSerArray(i);
//tx= ser.getTx();
// Category Axis Data
cat = ser.getCat();
// 获取图表的值
val = ser.getVal();
// strData.set
CTStrData strData = cat.getStrRef().getStrCache();
CTNumData numData = val.getNumRef().getNumCache();
strData.setPtArray((CTStrVal[]) null); // unset old axis text
numData.setPtArray((CTNumVal[]) null); // unset old values
// set model
long idx = 0;
for (int j = 0; j < dataList.size(); j++) {
//判断获取的值是否为空
String value = "0";
if (new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))) != null) {
value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();
}
if (!"0".equals(value)) {
CTNumVal numVal = numData.addNewPt();//序列值
numVal.setIdx(idx);
numVal.setV(value);
}
CTStrVal sVal = strData.addNewPt();//序列名称
sVal.setIdx(idx);
sVal.setV(dataList.get(j).get(fldNameArr.get(0)));
idx++;
}
numData.getPtCount().setVal(idx);
strData.getPtCount().setVal(idx);
//赋值横坐标数据区域
String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0)
.formatAsString("Sheet1", true);
cat.getStrRef().setF(axisDataRange);
//数据区域
String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position)
.formatAsString("Sheet1", true);
val.getNumRef().setF(numDataRange);
}
return result;
}
/**
* 刷新饼图数据方法
*
* @param typeChart
* @param serList
* @param dataList
* @param fldNameArr
* @param position
* @return
*/
public static boolean refreshPieStrGraphContent(Object typeChart,
List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, int position) {
boolean result = true;
//更新数据区域
for (int i = 0; i < serList.size(); i++) {
//CTSerTx tx=null;
CTAxDataSource cat = null;
CTNumDataSource val = null;
CTPieSer ser = ((CTPieChart) typeChart).getSerArray(i);
//tx= ser.getTx();
// Category Axis Data
cat = ser.getCat();
// 获取图表的值
val = ser.getVal();
// strData.set
CTStrData strData = cat.getStrRef().getStrCache();
CTNumData numData = val.getNumRef().getNumCache();
strData.setPtArray((CTStrVal[]) null); // unset old axis text
numData.setPtArray((CTNumVal[]) null); // unset old values
// set model
long idx = 0;
for (int j = 0; j < dataList.size(); j++) {
//判断获取的值是否为空
String value = "0";
if (new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))) != null) {
value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();
}
if (!"0".equals(value)) {
CTNumVal numVal = numData.addNewPt();//序列值
numVal.setIdx(idx);
numVal.setV(value);
}
CTStrVal sVal = strData.addNewPt();//序列名称
sVal.setIdx(idx);
sVal.setV(dataList.get(j).get(fldNameArr.get(0)));
idx++;
}
numData.getPtCount().setVal(idx);
strData.getPtCount().setVal(idx);
//赋值横坐标数据区域
String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0)
.formatAsString("Sheet1", true);
cat.getStrRef().setF(axisDataRange);
//数据区域
String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position)
.formatAsString("Sheet1", true);
val.getNumRef().setF(numDataRange);
}
return result;
}
/**
* 刷新内置excel数据
*
* @param chart
* @param dataList
* @param fldNameArr
* @param titleArr
* @return
*/
public static boolean refreshExcel(XWPFChart chart,
List<Map<String, String>> dataList, List<String> fldNameArr, List<String> titleArr) {
boolean result = true;
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("Sheet1");
//根据数据创建excel第一行标题行
for (int i = 0; i < titleArr.size(); i++) {
if (sheet.getRow(0) == null) {
sheet.createRow(0).createCell(i).setCellValue(titleArr.get(i) == null ? "" : titleArr.get(i));
} else {
sheet.getRow(0).createCell(i).setCellValue(titleArr.get(i) == null ? "" : titleArr.get(i));
}
}
//遍历数据行
for (int i = 0; i < dataList.size(); i++) {
Map<String, String> baseFormMap = dataList.get(i);//数据行
//fldNameArr字段属性
for (int j = 0; j < fldNameArr.size(); j++) {
if (sheet.getRow(i + 1) == null) {
if (j == 0) {
try {
sheet.createRow(i + 1).createCell(j).setCellValue(baseFormMap.get(fldNameArr.get(j)) == null ? "" : baseFormMap.get(fldNameArr.get(j)));
} catch (Exception e) {
if (baseFormMap.get(fldNameArr.get(j)) == null) {
sheet.createRow(i + 1).createCell(j).setCellValue("");
} else {
sheet.createRow(i + 1).createCell(j).setCellValue(baseFormMap.get(fldNameArr.get(j)));
}
}
}
} else {
BigDecimal b = new BigDecimal(baseFormMap.get(fldNameArr.get(j)));
double value = 0d;
if (b != null) {
value = b.doubleValue();
}
if (value == 0) {
sheet.getRow(i + 1).createCell(j);
} else {
sheet.getRow(i + 1).createCell(j).setCellValue(b.doubleValue());
}
}
}
}
// 更新嵌入的workbook
List<POIXMLDocumentPart> pxdList = chart.getRelations();
if (pxdList != null && pxdList.size() > 0) {
for (int i = 0; i < pxdList.size(); i++) {
if (pxdList.get(i).toString().contains("sheet")) {//判断为sheet再去进行更新表格数据
POIXMLDocumentPart xlsPart = pxdList.get(i);
OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream();
try {
wb.write(xlsOut);
xlsOut.close();
} catch (IOException e) {
e.printStackTrace();
result = false;
} finally {
if (wb != null) {
try {
wb.close();
} catch (IOException e) {
e.printStackTrace();
result = false;
}
}
}
break;
}
}
}
return result;
}
/**
* 设置表格样式
*
* @param cell
* @param fontName
* @param fontSize
* @param fontBlod
* @param alignment
* @param vertical
* @param fontColor
* @param bgColor
* @param cellWidth
* @param content
*/
public static void setWordCellSelfStyle(XWPFTableCell cell, String fontName, String fontSize, int fontBlod,
String alignment, String vertical, String fontColor,
String bgColor, String cellWidth, String content) {
//poi对字体大小设置特殊不支持小数但对原word字体大小做了乘2处理
BigInteger bFontSize = new BigInteger("24");
if (fontSize != null && !fontSize.equals("")) {
//poi对字体大小设置特殊不支持小数但对原word字体大小做了乘2处理
BigDecimal fontSizeBD = new BigDecimal(fontSize);
fontSizeBD = bd2.multiply(fontSizeBD);
fontSizeBD = fontSizeBD.setScale(0, BigDecimal.ROUND_HALF_UP);//这里取整
bFontSize = new BigInteger(fontSizeBD.toString());// 字体大小
}
// 设置单元格宽度
cell.setWidth(cellWidth);
//=====获取单元格
CTTc tc = cell.getCTTc();
//====tcPr开始====
CTTcPr tcPr = tc.getTcPr();//获取单元格里的<w:tcPr>
if (tcPr == null) {//没有<w:tcPr>创建
tcPr = tc.addNewTcPr();
}
// --vjc开始-->>
CTVerticalJc vjc = tcPr.getVAlign();//获取<w:tcPr> <w:vAlign w:val="center"/>
if (vjc == null) {//没有<w:w:vAlign/>创建
vjc = tcPr.addNewVAlign();
}
//设置单元格对齐方式
vjc.setVal(vertical.equals("top") ? STVerticalJc.TOP : vertical.equals("bottom") ? STVerticalJc.BOTTOM : STVerticalJc.CENTER); //垂直对齐
CTShd shd = tcPr.getShd();//获取<w:tcPr>里的<w:shd w:val="clear" w:color="auto" w:fill="C00000"/>
if (shd == null) {//没有<w:shd>创建
shd = tcPr.addNewShd();
}
// 设置背景颜色
shd.setFill(bgColor.substring(1));
//====tcPr结束====
//====p开始====
CTP p = tc.getPList().get(0);//获取单元格里的<w:p w:rsidR="00C36068" w:rsidRPr="00B705A0" w:rsidRDefault="00C36068" w:rsidP="00C36068">
//---ppr开始--->>>
CTPPr ppr = p.getPPr();//获取<w:p>里的<w:pPr>
if (ppr == null) {//没有<w:pPr>创建
ppr = p.addNewPPr();
}
// --jc开始-->>
CTJc jc = ppr.getJc();//获取<w:pPr>里的<w:jc w:val="left"/>
if (jc == null) {//没有<w:jc/>创建
jc = ppr.addNewJc();
}
//设置单元格对齐方式
jc.setVal(alignment.equals("left") ? STJc.LEFT : alignment.equals("right") ? STJc.RIGHT : STJc.CENTER); //水平对齐
// <<--jc结束--
// --pRpr开始-->>
CTParaRPr pRpr = ppr.getRPr(); //获取<w:pPr>里的<w:rPr>
if (pRpr == null) {//没有<w:rPr>创建
pRpr = ppr.addNewRPr();
}
CTFonts pfont = pRpr.getRFonts();//获取<w:rPr>里的<w:rFonts w:ascii="宋体" w:eastAsia="宋体" w:hAnsi="宋体"/>
if (pfont == null) {//没有<w:rPr>创建
pfont = pRpr.addNewRFonts();
}
//设置字体
pfont.setAscii(fontName);
pfont.setEastAsia(fontName);
pfont.setHAnsi(fontName);
CTOnOff pb = pRpr.getB();//获取<w:rPr>里的<w:b/>
if (pb == null) {//没有<w:b/>创建
pb = pRpr.addNewB();
}
//设置字体是否加粗
pb.setVal(fontBlod == 1 ? STOnOff.ON : STOnOff.OFF);
CTHpsMeasure psz = pRpr.getSz();//获取<w:rPr>里的<w:sz w:val="32"/>
if (psz == null) {//没有<w:sz w:val="32"/>创建
psz = pRpr.addNewSz();
}
// 设置单元格字体大小
psz.setVal(bFontSize);
CTHpsMeasure pszCs = pRpr.getSzCs();//获取<w:rPr>里的<w:szCs w:val="32"/>
if (pszCs == null) {//没有<w:szCs w:val="32"/>创建
pszCs = pRpr.addNewSzCs();
}
// 设置单元格字体大小
pszCs.setVal(bFontSize);
// <<--pRpr结束--
//<<<---ppr结束---
//---r开始--->>>
List<CTR> rlist = p.getRList(); //获取<w:p>里的<w:r w:rsidRPr="00B705A0">
CTR r = null;
if (rlist != null && rlist.size() > 0) {//获取第一个<w:r>
r = rlist.get(0);
} else {//没有<w:r>创建
r = p.addNewR();
}
//--rpr开始-->>
CTRPr rpr = r.getRPr();//获取<w:r w:rsidRPr="00B705A0">里的<w:rPr>
if (rpr == null) {//没有<w:rPr>创建
rpr = r.addNewRPr();
}
//->-
CTFonts font = rpr.getRFonts();//获取<w:rPr>里的<w:rFonts w:ascii="宋体" w:eastAsia="宋体" w:hAnsi="宋体" w:hint="eastAsia"/>
if (font == null) {//没有<w:rFonts>创建
font = rpr.addNewRFonts();
}
//设置字体
font.setAscii(fontName);
font.setEastAsia(fontName);
font.setHAnsi(fontName);
CTOnOff b = rpr.getB();//获取<w:rPr>里的<w:b/>
if (b == null) {//没有<w:b/>创建
b = rpr.addNewB();
}
//设置字体是否加粗
b.setVal(fontBlod == 1 ? STOnOff.ON : STOnOff.OFF);
CTColor color = rpr.getColor();//获取<w:rPr>里的<w:color w:val="FFFFFF" w:themeColor="background1"/>
if (color == null) {//没有<w:color>创建
color = rpr.addNewColor();
}
// 设置字体颜色
if (content.contains("")) {
color.setVal("43CD80");
} else if (content.contains("")) {
color.setVal("943634");
} else {
color.setVal(fontColor.substring(1));
}
CTHpsMeasure sz = rpr.getSz();
if (sz == null) {
sz = rpr.addNewSz();
}
sz.setVal(bFontSize);
CTHpsMeasure szCs = rpr.getSzCs();
if (szCs == null) {
szCs = rpr.addNewSz();
}
szCs.setVal(bFontSize);
//-<-
//<<--rpr结束--
List<CTText> tlist = r.getTList();
CTText t = null;
if (tlist != null && tlist.size() > 0) {//获取第一个<w:r>
t = tlist.get(0);
} else {//没有<w:r>创建
t = r.addNewT();
}
t.setStringValue(content);
//<<<---r结束---
}
}

View File

@ -1,299 +0,0 @@
package com.ruoyi.common.utils.chartForWord;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author shuaihua zang
* @date 2022/10/10
*/
public class PoiWordUtil {
/**
* @param doc docx解析对象
* @param tableIndex 第几个表格
*/
public static XWPFTable getTable(XWPFDocument doc, int tableIndex) {
return doc.getTables().get(tableIndex);
}
/**
* 为表格插入行数此处不处理表头所以从第二行开始
*
* @param table 需要插入数据的表格
* @param tableList 插入数据集合
* @param index 在几行后开始插入数据 1为第一行
*/
public static void insertTable(XWPFTable table, List<String[]> tableList, int index) {
//创建与数据一致的行数
for (int i = 0; i < tableList.size(); i++) {
table.createRow();
}
int length = table.getRows().size() - index;
for (int i = 0; i < length; i++) {
XWPFTableRow newRow = table.getRow(i + index);
List<XWPFTableCell> cells = newRow.getTableCells();
for (int j = 0; j < cells.size(); j++) {
XWPFTableCell cell = cells.get(j);
cell.setText(tableList.get(i)[j]);
}
}
}
/**
* 替换段落里面的变量
*
* @param doc 要替换的文档
* @param params 参数
*/
public static void replaceParams(XWPFDocument doc, Map<String, String> params) {
Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
XWPFParagraph paragraph;
while (iterator.hasNext()) {
paragraph = iterator.next();
replaceParam(paragraph, params);
}
}
/**
* 替换所有表格里面的变量
*
* @param doc 要替换的文档
*/
public static void replaceAllTableParams(XWPFDocument doc, Map<String, String> testMap) {
Iterator<XWPFTable> iterator = doc.getTablesIterator();
XWPFTable table;
List<XWPFTableRow> rows;
List<XWPFTableCell> cells;
List<XWPFParagraph> paras;
while (iterator.hasNext()) {
table = iterator.next();
//判断表格是需要替换还是需要插入判断逻辑有$为替换表格无$为插入
if (matcher(table.getText()).find()) {
rows = table.getRows();
for (XWPFTableRow row : rows) {
cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
paras = cell.getParagraphs();
for (XWPFParagraph para : paras) {
replaceParam(para, testMap);
}
}
}
}
}
}
/**
* 替换表格里面的变量
*/
public static void replaceTableParams(XWPFTable table, Map<String, String> testMap) {
List<XWPFTableRow> rows;
List<XWPFTableCell> cells;
List<XWPFParagraph> paras;
//判断表格是需要替换还是需要插入判断逻辑有$为替换表格无$为插入
if (matcher(table.getText()).find()) {
rows = table.getRows();
for (XWPFTableRow row : rows) {
cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
paras = cell.getParagraphs();
for (XWPFParagraph para : paras) {
replaceParam(para, testMap);
}
}
}
}
}
/**
* 正则匹配字符串
*
* @param str
* @return
*/
public static Matcher matcher(String str) {
Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
return pattern.matcher(str);
}
/**
* 替换段落里面的变量
*
* @param paragraph 要替换的段落
* @param params 参数
*/
public static void replaceParam(XWPFParagraph paragraph, Map<String, String> params) {
List<XWPFRun> runs;
Matcher matcher;
StringBuilder runText = new StringBuilder();
if (matcher(paragraph.getParagraphText()).find()) {
runs = paragraph.getRuns();
int j = runs.size();
for (int i = 0; i < j; i++) {
runText.append(runs.get(0).toString());
//保留最后一个段落在这段落中替换值保留段落样式
if (!((j - 1) == i)) {
paragraph.removeRun(0);
}
}
matcher = matcher(runText.toString());
if (matcher.find()) {
while ((matcher = matcher(runText.toString())).find()) {
runText = new StringBuilder(matcher.replaceFirst(String.valueOf(params.get(matcher.group(1)))));
}
runs.get(0).setText(runText.toString(), 0);
}
}
}
/**
* word单元格列合并 都以0开始计算
*
* @param table 表格
* @param row 合并列所在行
* @param startCell 开始列
* @param endCell 结束列
* @date 2020年4月8日 下午4:43:54
*/
public static void mergeCellsHorizontal(XWPFTable table, int row, int startCell, int endCell) {
for (int i = startCell; i <= endCell; i++) {
XWPFTableCell cell = table.getRow(row).getCell(i);
if (i == startCell) {
// The first merged cell is set with RESTART merge value
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
} else {
// Cells which join (merge) the first one, are set with CONTINUE
cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
}
}
}
/**
* word单元格行合并
*
* @param table 表格
* @param col 合并行所在列
* @param startRow 开始行
* @param endRow 结束行
* @date 2020年4月8日 下午4:46:18
*/
public static void mergeCellsVertically(XWPFTable table, int col, int startRow, int endRow) {
for (int i = startRow; i <= endRow; i++) {
XWPFTableCell cell = table.getRow(i).getCell(col);
if (i == startRow) {
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
} else {
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
}
}
}
/**
* 替换图片
* key 替换字段名称与word中相同
* value 图片地址
*/
public static void doParagraphs(XWPFDocument doc, Map<String, String> imgMap) {
List<XWPFParagraph> paragraphList = doc.getParagraphs();
if (paragraphList != null && paragraphList.size() > 0) {
for (XWPFParagraph paragraph : paragraphList) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
String text = run.getText(0);
if (text != null) {
String imgkey = text.replaceAll("\\{\\{@", "").replaceAll("}}", "");
String imgPath = imgMap.get(imgkey);
if (imgPath != null) {
if (imgPath.startsWith("http")) {
imgPath = saveToFile(imgPath);
}
saveLocalImg(run, imgPath);
}
}
}
}
}
}
/**
* 获取本地保存图片文件流
*
* @param imgPath
* @return FileInputStream
* @throws Exception
*/
private static void saveLocalImg(XWPFRun run, String imgPath) {
try (FileInputStream pictureData = new FileInputStream(imgPath)) {
run.setText("", 0);
run.addPicture(pictureData,
Document.PICTURE_TYPE_PNG, "img.png", Units.toEMU(200), Units.toEMU(200));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取网络图片流
*
* @return
*/
public static String saveToFile(String destUrl) {
HttpURLConnection httpUrl = null;
byte[] buf = new byte[1024];
int size = 0;
StringBuilder append = new StringBuilder()
.append("D:/fjFile/")
.append(IdUtil.simpleUUID())
.append(".png");
String fileUrl = append.toString();
try {
URL url = new URL(destUrl);
httpUrl = (HttpURLConnection) url.openConnection();
httpUrl.setConnectTimeout(5*1000);
httpUrl.setReadTimeout(5*1000);
httpUrl.connect();
try (BufferedInputStream bis = new BufferedInputStream(httpUrl.getInputStream());
FileOutputStream fos = new FileOutputStream(fileUrl)){
while ((size = bis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
fos.flush();
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(httpUrl!=null){
httpUrl.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return fileUrl;
}
}