poi在Word中生成各种图表(支持柱状、组合、环状图、折线图、等常用图)
poi版本
1.maven坐标
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
2.poi官网指出需要poi4.x.x版本抛弃了jdk1.7之前的版本,所以适应此版本需要将jdk升级,如果不想升级还有另一种办法就是,使用springBoot单独做一个服务为你的主项目提供一个接口,让主项目去调用生成word流让主项目去接收即可。
效果图
1.刷新之前

2.刷新之后

代码
public class PoiDemoWordTable {
public static void main(String[] args) throws Exception {
final String returnurl=“d://poi/test.docx”;
final String templateurl=“D://poi/onepage.docx”;
InputStream is = new FileInputStream(new File(templateurl));
XWPFDocument doc = new XWPFDocument(is);
replaceAll(doc);
//文件存在删除
try {
File file = new File(returnurl);
if (file.exists()) {
file.delete();
}
FileOutputStream fos = new FileOutputStream(returnurl);
doc.write(fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Description: 替换段落和表格中
*/
public static void replaceAll( XWPFDocument doc) throws InvalidFormatException, FileNotFoundException, IOException{
/**----------------------------处理段落------------------------------------**/
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) {
if (text.contains("${table1}")) {
run.setText("",0);
XmlCursor cursor = paragraph.getCTP().newCursor();
XWPFTable tableOne = doc.insertNewTbl(cursor);// ---这个是关键
XWPFTableRow tableOneRowOne = tableOne.getRow(0);//行
setWordCellSelfStyle(tableOneRowOne.getCell(0),"微软雅黑","9",1,"left","top","#ffffff","#4472C4",1,"序号");
XWPFTableCell cell12 = tableOneRowOne.createCell();
setWordCellSelfStyle(cell12,"微软雅黑","9",1,"left","top","#ffffff","#4472C4",1,"公司名称(英文)");
XWPFTableCell cell13 = tableOneRowOne.createCell();
setWordCellSelfStyle(cell13,"微软雅黑","9",1,"left","top","#ffffff","#4472C4",1,"公司名称(中文)");
XWPFTableRow tableOneRowTwo = tableOne.createRow();//行
tableOneRowTwo.getCell(0).setText("第二行第一列");
setWordCellSelfStyle(tableOneRowTwo.getCell(0),"微软雅黑","9",0,"left","top","#000000","#B4C6E7",1,"一行一列");
tableOneRowTwo.getCell(1).setText("第二行第二列");
setWordCellSelfStyle(tableOneRowTwo.getCell(1),"微软雅黑","9",0,"left","top","#000000","#B4C6E7",1,"一行一列");
tableOneRowTwo.getCell(2).setText("第二行第二列");
setWordCellSelfStyle(tableOneRowTwo.getCell(2),"微软雅黑","9",0,"left","top","#000000","#B4C6E7",1,"一行一列");
XWPFTableRow tableOneRowThree = tableOne.createRow();//行
tableOneRowThree.getCell(0).setText("第三行第一列");
setWordCellSelfStyle(tableOneRowThree.getCell(0),"微软雅黑","9",0,"left","top","#000000","#D9E2F3",1,"一行一列");
tableOneRowThree.getCell(1).setText("第三行第二列");
setWordCellSelfStyle(tableOneRowThree.getCell(1),"微软雅黑","9",0,"left","top","#000000","#D9E2F3",1,"一行一列");
tableOneRowThree.getCell(2).setText("第三行第二列");
setWordCellSelfStyle(tableOneRowThree.getCell(2),"微软雅黑","9",0,"left","top","#000000","#D9E2F3",1,"一行一列");
}else{//动态图表
List<String> showtailArr=new ArrayList<String>();
showtailArr.add("0");
showtailArr.add("2");
List<String> ispercentArr=new ArrayList<String>();
ispercentArr.add("0");
ispercentArr.add("0");
List<String> titleArr = new ArrayList<String>();// 标题
titleArr.add("行业类别");
titleArr.add("占基金资产净值比例(%)");
List<String> fldNameArr = new ArrayList<String>();// 字段名
fldNameArr.add("item1");
fldNameArr.add("item3");
List<Map<String,String>> listItemsByType=new ArrayList<Map<String,String>>();
Map<String,String> base1=new HashMap<String,String>();//相当于HashMap
base1.put("item1","材料费用");
base1.put("item3","500.10");
Map<String,String> base2=new HashMap<String,String>();//相当于HashMap
base2.put("item1","出差费用");
base2.put("item3","300.10");
listItemsByType.add(base1);
listItemsByType.add(base2);
//动态刷新图表
List<POIXMLDocumentPart> relations = doc.getRelations();
for (POIXMLDocumentPart poixmlDocumentPart : relations) {
if (poixmlDocumentPart instanceof XWPFChart) {
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, showtailArr, ispercentArr);
//刷新页面显示数
refreshStrGraphContent(barChart, barSerList, listItemsByType, fldNameArr, titleArr, showtailArr, ispercentArr, 1);
}
}
}
}
}
}
}
}
/**
* @Description:刷新数据方法(str进行分类)
* @param typeChart:传递的图形类型
* @param serList:传递的serList(数据)
* @param dataList:显示的数据
* @param fldNameArr:属性列
* @param position:取数的列
* @return boolean
* @author nieds
* @date 2019年6月11日上午10:36:56
*
*/
public static boolean refreshStrGraphContent(Object typeChart,
List<?> serList, List<Map<String,String>> dataList, List<String> fldNameArr,List<String> titleArr,List<String>showtailArr,List<String> ispercentArr, 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);
if("1".equals(ispercentArr.get(i+position))){//是否设置百分比
// 设置Y轴的数字为百分比样式显示
StringBuilder sb=new StringBuilder();
if("0".equals(showtailArr.get(i+position))){//保留几位小数
sb.append("0");
if("1".equals(ispercentArr.get(i+position))){//是否百分比
sb.append("%");
}
}else{
sb.append("0.");
for(int k=0;k<Integer.parseInt(showtailArr.get(i+position));k++){
sb.append("0");
}
if("1".equals(ispercentArr.get(i+position))){//是否百分比
sb.append("%");
}
}
val.getNumRef().getNumCache().setFormatCode(sb.toString());
}else{
//是否设置百分比
// 设置Y轴的数字为百分比样式显示
StringBuilder sb=new StringBuilder();
if("0".equals(showtailArr.get(i+position))){//保留几位小数
sb.append("0");
}else{
sb.append("0.");
for(int k=0;k<Integer.parseInt(showtailArr.get(i+position));k++){
sb.append("0");
}
}
val.getNumRef().getNumCache().setFormatCode(sb.toString());
}
}
return result;
}
public static boolean refreshExcel(XWPFChart chart,
List<Map<String,String>> dataList,List<String> fldNameArr,List<String> titleArr,
List<String> showtailArr,List<String> ispercentArr) {
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());
}
if("1".equals(ispercentArr.get(j))){//是否设置百分比
// 设置Y轴的数字为百分比样式显示
StringBuilder sb=new StringBuilder();
if("0".equals(showtailArr.get(j))){//保留几位小数
sb.append("0");
if("1".equals(ispercentArr.get(j))){//是否百分比
sb.append("%");
}
}else{
sb.append("0.");
for(int k=0;k<Integer.parseInt(showtailArr.get(j));k++){
sb.append("0");
}
if("1".equals(ispercentArr.get(j))){//是否百分比
sb.append("%");
}
}
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(wb.createDataFormat().getFormat(sb.toString()));
sheet.getRow(i+1).getCell(j).setCellStyle(cellStyle);
}else{
//是否设置百分比
// 设置Y轴的数字为百分比样式显示
StringBuilder sb=new StringBuilder();
if("0".equals(showtailArr.get(j))){//保留几位小数
sb.append("0");
}else{
sb.append("0.");
for(int k=0;k<Integer.parseInt(showtailArr.get(j));k++){
sb.append("0");
}
}
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(wb.createDataFormat().getFormat(sb.toString()));
sheet.getRow(i+1).getCell(j).setCellStyle(cellStyle);
}
}
}
}
// 更新嵌入的workbook
POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
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;
}
}
}
return result;
}
private static final BigDecimal bd2 = new BigDecimal("2");
private static void setWordCellSelfStyle(XWPFTableCell cell, String fontName, String fontSize, int fontBlod,
String alignment, String vertical, String fontColor,
String bgColor, long 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());// 字体大小
}
//=====获取单元格
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结束---
}
}

该博客介绍了如何利用Apache POI库在Word文档中生成多种图表,包括柱状图、组合图、环状图和折线图。通过提供的代码示例,展示了在Java中操作Word图表的详细步骤。
3826

被折叠的 条评论
为什么被折叠?



