精华内容
下载资源
问答
  • pandas excel处理数据和生成折线图

    千次阅读 2019-09-04 15:36:45
    plt.title('start app time test') #设置折线图标题 plt.xlabel('build',fontsize=5) #设置x标注 plt.ylabel('time',fontsize=5) plt.xticks(fontsize=4) #x字体 plt.yticks(fontsize=4) #plt.subplot(figsize=(10,5...
    import pandas
    from matplotlib import pyplot as plt
    from matplotlib.font_manager import FontProperties
    import os
    import numpy
    
    get_path=lambda p:os.path.join(os.path.dirname(__file__),'../result/%s'%p)
    #get_path=lambda p:os.path.abspath(os.path.join(os.path.dirname(__file__),p))
    
    plt.title('start app time test')  #设置折线图标题
    plt.xlabel('build',fontsize=5)  #设置x标注
    plt.ylabel('time',fontsize=5)
    plt.xticks(fontsize=4)  #x字体
    plt.yticks(fontsize=4)
    #plt.subplot(figsize=(10,5)
    
    #oe=Operation_excel(file)
    def save_png(excel_file,out_file,out_excel,png_key=None):
    
        df=pandas.read_excel(get_path(excel_file))  #读取excel表格
        df=df[df['时间/s']!='error_log']  #过滤掉“时间/s”这一列为error_log的行
        if png_key==None:
            df=df[df['帐号类型'] == 'logout'] #筛选出帐号类型为logout的数据
        df['时间/s']=df['时间/s'].astype('float')  #转换“时间/s”这一列数据类型
        print(df.dtypes)  #打印出表格数据第一列
        dre=pandas.pivot_table(df,index=['机型','帐号类型'],columns='build',values='时间/s')  #已机型,帐号类型分类,筛选出不同build的时间/s的平均值
        dfe=pandas.pivot_table(df,index=['机型','帐号类型'],columns='build',values='时间/s',aggfunc=numpy.var)
        dre.to_excel(get_path(out_excel))  #保存转换过得表格
        dfe.to_excel(get_path('var'+out_excel))
        # print(dre.index.values)
        # print(dre.values)
        devices=[]
        x=[i for i in dre.dtypes.index]
        if png_key is None:
            plt.figure(figsize=(3*len(x),6))  #设置x轴长度,各个元素乘以3
            plt.title('android start time static',FontProperties='STKAITI')
        sl=set([i[0] for i in dre.index.values])
        for s in sl:
            print(s)
            if png_key is not None:
                plt.figure()
                plt.xticks(fontsize=4)
                plt.yticks(fontsize=4)
            for i in dre.index.values:
                if s in i:
                    y = []
                    devices.append(i)
                    print(i)
                    data = dre.loc[i,x]  #index为i的所有x值
                    for j in data:
                        y.append(j)
                    print(y)
                    plt.plot(x,y,label=i,linewidth=3)
                    plt.legend()
            if png_key is not None:
                plt.savefig(get_path(s+out_file), dpi=800)
        if png_key is None:
            plt.savefig(get_path(out_file),dpi=800)
    展开全文
  • 一、准备需要模块:from openpyxl.workbook import Workbookfrom openpyxl.chart import Series,LineChart, Reference1.1 建表,画图openpyxl支持利用工作表中单元格的数据,创建条形图、折线图、散点图等步骤:wb =...

    一、准备

    需要模块:

    from openpyxl.workbook import Workbook

    from openpyxl.chart import Series,LineChart, Reference

    1.1 建表,画图

    openpyxl支持利用工作表中单元格的数据,创建条形图、折线图、散点图等

    步骤:

    wb = Workbook()

    ws = wb.create_sheet("{0}蒸汽压力记录表".format("样品名称"), 0)

    从将表格中涉及的要画图的数据使用:Reference 创建一个对象

    比如:我选取 data = Reference(ws, min_col=5, min_row=4, max_col=10, max_row=4)

    参数含义:ws 一个活跃的sheet,数据来源。可以使用ws = wb.active 获取

    其他的就是指定这个表中的行列数据了:起始行、起始列、终止行、终止列

    通过传入Reference对象,创建一个Series对象

    创建一个Chart对象

    可选择的设置Chart对象的长(drawing.height)、宽(drawing.width)、坐标位置(drawing.top、drawing.left)。

    将Chart对象添加到Worksheet对象。

    chart = LineChart() #图表对象

    data = Reference(ws, min_col=5, min_row=4, max_col=10, max_row=4) #涉及数据

    seriesObj = Series(data, title='压力') #创建series对象

    chart.append(seriesObj) #添加到chart中

    ws.add_chart(chart, "A6") #将图表添加到 sheet中

    1.2 其他方式画图

    一个饼图

    from openpyxl import load_workbook

    from openpyxl import Workbook

    from openpyxl.chart import BarChart, Reference, Series

    wb = load_workbook('e:\\sample.xlsx')

    ws1=wb.active

    wb = Workbook()

    ws = wb.active

    for i in range(10):

    ws.append([i])

    values = Reference(ws, min_col=1, min_row=1, max_col=1, max_row=10)

    chart = BarChart()

    chart.add_data(values)

    ws.add_chart(chart, "E15")

    # Save the file

    wb.save("e:\\sample.xlsx")

    3.1.2 作者最近工作用的一个图

    9dee1b1aa2ab6ad58f8a98a7731f37a3

    import uuid

    import string

    import json

    import time

    import os

    import base64

    from openpyxl.workbook import Workbook

    from openpyxl.styles import Font, Alignment, Side, Border

    from openpyxl.drawing import image

    from openpyxl.chart import Series,LineChart, Reference

    from Lib.Utils import Utils

    class ExportReport:

    def __init__(self, start_time, water_temp, test_people,

    sample_name, pressure_value, pressure_list,*args, **kwargs):

    """

    :param start_time: 实验开始时间

    :param water_temp: 水浴温度

    :param test_people: 试验人

    :param sample_name: 样品名称

    :param pressure_value: 最终压力

    :param args: 实验过程压力记录列表

    :param kwargs:

    """

    self.start_time = start_time

    self.water_temp = str(water_temp)+' ℃'

    self.test_people = test_people

    self.sample_name = sample_name

    self.pressure_value = pressure_value

    self.all_col = 5+len(pressure_list) #一共多少列

    self.pressure_record = pressure_list #第六列到最后一列的数据列表

    self.image_path = kwargs.get('imgPath', None) #图片路径

    #所有的数据列

    self.data_list = [

    self.start_time, self.water_temp,

    self.test_people,self.sample_name,

    self.pressure_value

    ]

    self.data_list.extend(self.pressure_record)

    self.col_list = ["开始时间", "水浴温度", "测试人", "样品名称", "最终压力值"]

    # base64转化为图片

    # self.bs64 = bs64

    # self.img_path = Utils.change_base64_as_img(self.bs64)

    self.wb = Workbook()

    #self.wb.remove(self.wb["sheet"])

    self.ws = self.wb.create_sheet("{0}蒸汽压力记录表".format(self.sample_name), 0)

    #生成所含列总数的大写字母

    self.upper_string_list = string.ascii_uppercase[:self.all_col]

    # 水平对齐,居中对齐

    self.alignment_style = Alignment(horizontal='center', vertical='center')

    #定义border 边框样式

    left, right, top, bottom = [Side(style='thin', color='000000')]*4

    self.border_style = Border(left=left, right=right, top=top, bottom=bottom)

    #定义字体

    self.font_size = Font(size=9)

    for col in self.upper_string_list:

    self.ws.column_dimensions[col].width = 20

    #单元格样式字体调整

    def cell_set(self, cellObj, fontSzie=12, alignmentStyle=None):

    alignmentStyle = alignmentStyle if alignmentStyle else self.alignment_style

    cellObj.alignment = alignmentStyle

    cellObj.font = Font(size=fontSzie, bold=True)

    #创建表头第一行

    def create_row1(self):

    #把所有列合并

    self.ws.merge_cells(start_row=1, end_row=1, start_column=1, end_column=self.all_col)

    #写入值

    # self.ws.cell(row=1, column=1).value = value

    self.ws.cell(row=1, column=1).value = "{0}蒸汽压力记录表".format(self.sample_name)

    # self.ws['A1'].alignment = self.alignment_style

    # self.ws['A1'].font = Font(size=16, bold=True)

    self.cell_set(self.ws['A1'], 16)

    self.create_row2_3()

    def create_row2_3(self):

    #把前五列,二三行单元格合并,并写入值

    for col in range(1, len(self.col_list)+1):

    self.ws.merge_cells(start_row=2, end_row=3, start_column=col, end_column=col)

    col_str = self.upper_string_list[col-1]+"2"

    self.ws[col_str] = self.col_list[col-1]

    # self.ws[col_str].alignment = self.alignment_style

    # self.ws[col_str].font = Font(size=12, bold=True)

    self.cell_set(self.ws[col_str])

    #把第二行第六列开始到最后列合并

    self.ws.merge_cells(start_row=2, end_row=2, start_column=len(self.col_list)+1, end_column=self.all_col)

    col_str = self.upper_string_list[len(self.col_list)]+"2"

    self.ws[col_str] = "实验过程压力记录"

    # self.ws[col_str].alignment = self.alignment_style

    # self.ws[col_str].font = Font(size=12, bold=True)

    self.cell_set(self.ws[col_str])

    #第三行第六列开始到最后列写入值

    for index, col_ltr in enumerate(self.upper_string_list[len(self.col_list):]):

    col_str = col_ltr+'3'

    self.ws[col_str] = "第{0}次压力记录".format(index+1)

    # self.ws[col_str].alignment = self.alignment_style

    # self.ws[col_str].font = Font(size=12, bold=True)

    self.cell_set(self.ws[col_str])

    def add_data(self):

    #第四行开始写入数据,所有数据居中对齐,水平居中

    for index, col in enumerate(self.upper_string_list):

    col_str = col+"4"

    self.ws[col_str] = self.data_list[index]

    # self.ws[col_str].alignment = self.alignment_style

    # self.ws[col_str].font = Font(size=12, bold=True)

    self.cell_set(self.ws[col_str])

    #画折线图

    def draw_line_chart(self):

    data_col = self.ws["{0}:{1}".format(self.upper_string_list[len(self.col_list)]+"3",self.upper_string_list[-1]+"3" )]

    self.chart = LineChart()

    self.chart.width = 21.2

    self.chart.height = 8

    self.chart.style = 2 ##线条的style,Max value is 48 2 10

    self.chart.title = "压力记录图"

    self.chart.y_axis.title = "压力值"

    self.chart.x_axis.title = "压力测量次数"

    #从活动表中关联压力记录次数数据, 第六行到第10行

    data = Reference(

    self.ws,

    min_col=len(self.col_list)+1,

    min_row=4,

    max_col=self.all_col,

    max_row=4

    )

    #将数据添加到系列中

    seriesObj = Series(data, title='压力')

    format_str = "第{0}次记录:/n压力:{1}".format(seriesObj.xVal,seriesObj.yVal)

    # seriesObj.labels

    self.chart.append(seriesObj)

    # self.chart.add_data(data, from_rows=False)

    # style = self.chart.series[0]

    # style.smooth = True

    self.ws.add_chart(self.chart, "A6")

    def create(self,value=None):

    if value:

    self.ws.cell(row=1, column=1).value = value

    self.create_row1()

    self.add_data()

    self.draw_line_chart()

    def save(self, filename):

    try:

    self.wb.save(filename)

    except:

    self.wb.save(filename[:-5] + str('_' + Utils.getFileName()) + filename[-5:])

    # 关闭excel

    self.close()

    def close(self):

    self.wb.close()

    if __name__ == '__main__':

    er = ExportReport(1, 2, 3, 4, 5, [17, 15, 19, 13,24])

    er.create()

    er.wb.save('17表.xlsx')

    展开全文
  • 参考文章的基础上,增加了扩展。感谢被参考的老哥。 代码直接从日记中复制过来的,不方便复制的可以私信发示例代码,不知道怎么上传附件了。 代码有的地方写的不合理或者错误的,请原谅没有检查仔细; 说明:...

    本文参考地址:https://blog.csdn.net/wangxiaoyingWXY/article/details/95377533
    在参考文章的基础上,增加了扩展。感谢被参考的妹子。另外该博客主要记录很多poi操作word中遇到的问题和解决方式,所以会一直维护下去。

    另外,我是在本地使用的wps,使用office的老哥(老姐)们可能在效果上有出入。

    本文只是简单示例,仅做代码参考,在实际运用中可自行根据业务封装。

    模板在示例代码中有的哈,在resource目录下面

    还有就是博主真的很菜.....(手动滑稽)

    关于示例代码:(码云地址)https://gitee.com/loverer/poi-demo

    另外如果遇到模板标签不完整的情况,请参考:https://blog.csdn.net/weixin_43770790/article/details/86672962

    说明:在poi3.x的版本中,没有对图表的支持,至少目前为止没有找到相应的文章介绍;在poi4.x的版本中加入了对图表的支持,所以需要引入poi4.x的依赖包,并且JDK最低版本要求8;

    2019-12-04:新增:动态刷新内置Excel数据

    2020-04-07:新增:更新插入的文本框内容(感谢博友:输过败过但不曾怕过啊)

    2020-04-10:新增:新增一个定位图表的方式(感谢博友:输过败过但不曾怕过啊)

    2020-04-11:新增:柱状图动态列,优化修改(兼容wps和office)(感谢:谈个长长的恋爱可好)

    2020-04-21:新增:表格进行合并单元格,横竖都行,两种方式(感谢刘老师)

    2020-04-23:解决问题:组合图页面显示的数据,跟第二列对应不上(感谢博友:吹古拉朽)

    2020-06-06:解决问题:图表设置系列标题方式错误导致office无法打开的问题(感谢博友: qq_18900373)

    // 设置标题
    CTSerTx tx = ser.getTx();
    tx.setV("阿里嘎痛");  // wps可以打开,office无法打开
    tx.getStrRef().getStrCache().getPtList().get(0).setV("阿里嘎痛"); // wps和office都能打开

    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>

    完整pom.xml内容

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
       <modelVersion>4.0.0</modelVersion>
       <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>2.1.8.RELEASE</version>
          <relativePath/> <!-- lookup parent from repository -->
       </parent>
       <groupId>com.example</groupId>
       <artifactId>demo</artifactId>
       <version>0.0.1-SNAPSHOT</version>
       <name>demo</name>
       <description>Demo project for Spring Boot</description>
    
       <properties>
          <java.version>1.8</java.version>
       </properties>
    
       <dependencies>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
          </dependency>
    
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-devtools</artifactId>
             <scope>runtime</scope>
             <optional>true</optional>
          </dependency>
          <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
             <optional>true</optional>
          </dependency>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
          </dependency>
    
          <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流让主项目去接收即可。-->
    
    
    
       </dependencies>
    
       <build>
          <plugins>
             <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
             </plugin>
          </plugins>
       </build>
    
    </project>

    2.准备word模板文件,注意后缀是docx,模板中的图表可以有数据,但是最终会被代码替换,所以不重要

    模板文件: 不知道怎么上传了,需要的私信吧,感谢;

    3.两个类

    类1:PoiDemoWordTable 

    package com.example.demo;
    
    import com.example.demo.util.PoiWordTools;
    
    import org.apache.poi.ooxml.POIXMLDocumentPart;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.util.Units;
    import org.apache.poi.xwpf.usermodel.*;
    import org.apache.xmlbeans.XmlCursor;
    import org.springframework.util.StringUtils;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class PoiDemoWordTable {
    
        public static void main(String[] args) throws Exception {
    
            final String returnurl = "D:\\youxi\\jx\\result.docx";  // 结果文件
    
            final String templateurl = "D:\\youxi\\jx\\test.docx";  // 模板文件
    
            InputStream is = new FileInputStream(new File(templateurl));
            XWPFDocument doc = new XWPFDocument(is);
    
            // 替换word模板数据
            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, IOException {
            doParagraphs(doc); // 处理段落文字数据,包括文字和表格、图片
            doCharts(doc);  // 处理图表数据,柱状图、折线图、饼图啊之类的
        }
    
    
        /**
         * 处理段落文字
         *
         * @param doc
         * @throws InvalidFormatException
         * @throws FileNotFoundException
         * @throws IOException
         */
        public static void doParagraphs(XWPFDocument doc) throws InvalidFormatException, IOException {
    
            // 文本数据
            Map<String, String> textMap = new HashMap<String, String>();
            textMap.put("var", "我是被替换的文本内容");
    
            // 图片数据
            Map<String, String> imgMap = new HashMap<String, String>();
            imgMap.put("img", "D:/youxi/ddd.png");
    
    
            /**----------------------------处理段落------------------------------------**/
            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 tempText = text;
                            String key = tempText.replaceAll("\\{\\{", "").replaceAll("}}", "");
                            if (!StringUtils.isEmpty(textMap.get(key))) {
                                run.setText(textMap.get(key), 0);
                            }
    
                            // 替换图片内容 参考:https://blog.csdn.net/a909301740/article/details/84984445
                            String tempImgText = text;
                            String imgkey = tempImgText.replaceAll("\\{\\{@", "").replaceAll("}}", "");
                            if (!StringUtils.isEmpty(imgMap.get(imgkey))) {
                                String imgPath = imgMap.get(imgkey);
                                try {
                                    run.setText("", 0);
                                    run.addPicture(new FileInputStream(imgPath), Document.PICTURE_TYPE_PNG, "img.png", Units.toEMU(200), Units.toEMU(200));
    
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
    
                            // 动态表格
                            if (text.contains("${table1}")) {
                                run.setText("", 0);
                                XmlCursor cursor = paragraph.getCTP().newCursor();
                                XWPFTable tableOne = doc.insertNewTbl(cursor);// ---这个是关键
    
                                // 设置表格宽度,第一行宽度就可以了,这个值的单位,目前我也还不清楚,还没来得及研究
                                tableOne.setWidth(8500);
    
                                // 表格第一行,对于每个列,必须使用createCell(),而不是getCell(),因为第一行嘛,肯定是属于创建的,没有create哪里来的get呢
                                XWPFTableRow tableOneRowOne = tableOne.getRow(0);//行
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowOne.getCell(0), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "10%", "序号");
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowOne.createCell(), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "公司名称(英文)");
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowOne.createCell(), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "公司名称(中文)");
    
                                // 表格第二行
                                XWPFTableRow tableOneRowTwo = tableOne.createRow();//行
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowTwo.getCell(0), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "10%", "一行一列");
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowTwo.getCell(1), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "一行一列");
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowTwo.getCell(2), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "一行一列");
    
    
                                // ....... 可动态添加表格
                            }
                        }
                    }
                }
            }
        }
    
    
        /**
         * 处理图表
         *
         * @param doc
         * @throws FileNotFoundException
         */
        public static void doCharts(XWPFDocument doc) throws FileNotFoundException {
            /**----------------------------处理图表------------------------------------**/
    
            // 数据准备
            List<String> titleArr = new ArrayList<String>();// 标题
            titleArr.add("title");
            titleArr.add("金额");
    
            List<String> fldNameArr = new ArrayList<String>();// 字段名
            fldNameArr.add("item1");
            fldNameArr.add("item2");
    
            // 数据集合
            List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
    
            // 第一行数据
            Map<String, String> base1 = new HashMap<String, String>();
            base1.put("item1", "材料费用");
            base1.put("item2", "500");
    
            // 第二行数据
            Map<String, String> base2 = new HashMap<String, String>();
            base2.put("item1", "出差费用");
            base2.put("item2", "300");
    
            // 第三行数据
            Map<String, String> base3 = new HashMap<String, String>();
            base3.put("item1", "住宿费用");
            base3.put("item2", "300");
    
            listItemsByType.add(base1);
            listItemsByType.add(base2);
            listItemsByType.add(base3);
    
    
            // 获取word模板中的所有图表元素,用map存放
            // 为什么不用list保存:查看doc.getRelations()的源码可知,源码中使用了hashMap读取文档图表元素,
            // 对relations变量进行打印后发现,图表顺序和文档中的顺序不一致,也就是说relations的图表顺序不是文档中从上到下的顺序
            Map<String, POIXMLDocumentPart> chartsMap = new HashMap<String, POIXMLDocumentPart>();
            //动态刷新图表
            List<POIXMLDocumentPart> relations = doc.getRelations();
            for (POIXMLDocumentPart poixmlDocumentPart : relations) {
                if (poixmlDocumentPart instanceof XWPFChart) {  // 如果是图表元素
                    String str = poixmlDocumentPart.toString();
                    System.out.println("str:" + str);
                    String key = str.replaceAll("Name: ", "")
                            .replaceAll(" - Content Type: application/vnd\\.openxmlformats-officedocument\\.drawingml\\.chart\\+xml", "").trim();
                    System.out.println("key:" + key);
    
                    chartsMap.put(key, poixmlDocumentPart);
                }
            }
    
            System.out.println("\n图表数量:" + chartsMap.size() + "\n");
    
    
            // 第一个图表-条形图
            POIXMLDocumentPart poixmlDocumentPart0 = chartsMap.get("/word/charts/chart1.xml");
            new PoiWordTools().replaceBarCharts(poixmlDocumentPart0, titleArr, fldNameArr, listItemsByType);
    
            // 第二个-柱状图
            POIXMLDocumentPart poixmlDocumentPart1 = chartsMap.get("/word/charts/chart2.xml");
            new PoiWordTools().replaceBarCharts(poixmlDocumentPart1, titleArr, fldNameArr, listItemsByType);
    
            // 第三个图表-多列柱状图
            doCharts3(chartsMap);
    
            // 第四个图表-折线图
            doCharts4(chartsMap);
    
            // 第五个图表-饼图
            POIXMLDocumentPart poixmlDocumentPart4 = chartsMap.get("/word/charts/chart5.xml");
            new PoiWordTools().replacePieCharts(poixmlDocumentPart4, titleArr, fldNameArr, listItemsByType);
    
    
            doCharts6(chartsMap);
        }
    
    
        public static void doCharts3(Map<String, POIXMLDocumentPart> chartsMap) {
            // 数据准备
            List<String> titleArr = new ArrayList<String>();// 标题
            titleArr.add("姓名");
            titleArr.add("欠款");
            titleArr.add("存款");
    
            List<String> fldNameArr = new ArrayList<String>();// 字段名
            fldNameArr.add("item1");
            fldNameArr.add("item2");
            fldNameArr.add("item3");
    
            // 数据集合
            List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
    
            // 第一行数据
            Map<String, String> base1 = new HashMap<String, String>();
            base1.put("item1", "老张");
            base1.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base1.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第二行数据
            Map<String, String> base2 = new HashMap<String, String>();
            base2.put("item1", "老李");
            base2.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base2.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第三行数据
            Map<String, String> base3 = new HashMap<String, String>();
            base3.put("item1", "老刘");
            base3.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base3.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
    
            listItemsByType.add(base1);
            listItemsByType.add(base2);
            listItemsByType.add(base3);
    
            POIXMLDocumentPart poixmlDocumentPart2 = chartsMap.get("/word/charts/chart3.xml");
            new PoiWordTools().replaceBarCharts(poixmlDocumentPart2, titleArr, fldNameArr, listItemsByType);
        }
    
    
    
        public static void doCharts4(Map<String, POIXMLDocumentPart> chartsMap) {
            // 数据准备
            List<String> titleArr = new ArrayList<String>();// 标题
            titleArr.add("title");
            titleArr.add("占基金资产净值比例22222(%)");
            titleArr.add("额外的(%)");
            titleArr.add("额外的(%)");
    
            List<String> fldNameArr = new ArrayList<String>();// 字段名
            fldNameArr.add("item1");
            fldNameArr.add("item2");
            fldNameArr.add("item3");
            fldNameArr.add("item4");
    
            // 数据集合
            List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
    
            // 第一行数据
            Map<String, String> base1 = new HashMap<String, String>();
            base1.put("item1", "材料费用");
            base1.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base1.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base1.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第二行数据
            Map<String, String> base2 = new HashMap<String, String>();
            base2.put("item1", "出差费用");
            base2.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base2.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base2.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第三行数据
            Map<String, String> base3 = new HashMap<String, String>();
            base3.put("item1", "住宿费用");
            base3.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base3.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base3.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
    
            listItemsByType.add(base1);
            listItemsByType.add(base2);
            listItemsByType.add(base3);
    
            POIXMLDocumentPart poixmlDocumentPart2 = chartsMap.get("/word/charts/chart4.xml");
            new PoiWordTools().replaceLineCharts(poixmlDocumentPart2, titleArr, fldNameArr, listItemsByType);
        }
    
    
        /**
         * 对应文档中的第6个图表(预处理—分公司情况)
         */
        public static void doCharts6(Map<String, POIXMLDocumentPart> chartsMap) {
            // 数据准备
            List<String> titleArr = new ArrayList<String>();// 标题
            titleArr.add("title");
            titleArr.add("投诉受理量(次)");
            titleArr.add("预处理拦截工单量(次)");
            titleArr.add("拦截率");
    
            List<String> fldNameArr = new ArrayList<String>();// 字段名
            fldNameArr.add("item1");
            fldNameArr.add("item2");
            fldNameArr.add("item3");
            fldNameArr.add("item4");
    
            // 数据集合
            List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
    
            // 第一行数据
            Map<String, String> base1 = new HashMap<String, String>();
            base1.put("item1", "通辽");
            base1.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base1.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base1.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第二行数据
            Map<String, String> base2 = new HashMap<String, String>();
            base2.put("item1", "呼和浩特");
            base2.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base2.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base2.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第三行数据
            Map<String, String> base3 = new HashMap<String, String>();
            base3.put("item1", "锡林郭勒");
            base3.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base3.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base3.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第四行数据
            Map<String, String> base4 = new HashMap<String, String>();
            base4.put("item1", "阿拉善");
            base4.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base4.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base4.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第五行数据
            Map<String, String> base5 = new HashMap<String, String>();
            base5.put("item1", "巴彦淖尔");
            base5.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base5.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base5.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第六行数据
            Map<String, String> base6 = new HashMap<String, String>();
            base6.put("item1", "兴安");
            base6.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base6.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base6.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第七行数据
            Map<String, String> base7 = new HashMap<String, String>();
            base7.put("item1", "乌兰察布");
            base7.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base7.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base7.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第八行数据
            Map<String, String> base8 = new HashMap<String, String>();
            base8.put("item1", "乌海");
            base8.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base8.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base8.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第九行数据
            Map<String, String> base9 = new HashMap<String, String>();
            base9.put("item1", "赤峰");
            base9.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base9.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base9.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第十行数据
            Map<String, String> base10 = new HashMap<String, String>();
            base10.put("item1", "包头");
            base10.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base10.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base10.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第十一行数据
            Map<String, String> base11 = new HashMap<String, String>();
            base11.put("item1", "呼伦贝尔");
            base11.put("item2", (int)(int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base11.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base11.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第十二行数据
            Map<String, String> base12 = new HashMap<String, String>();
            base12.put("item1", "鄂尔多斯");
            base12.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base12.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base12.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            listItemsByType.add(base1);
            listItemsByType.add(base2);
            listItemsByType.add(base3);
            listItemsByType.add(base4);
            listItemsByType.add(base5);
            listItemsByType.add(base6);
            listItemsByType.add(base7);
            listItemsByType.add(base8);
            listItemsByType.add(base9);
            listItemsByType.add(base10);
            listItemsByType.add(base11);
            listItemsByType.add(base12);
    
            // 下标0的图表-折线图
            POIXMLDocumentPart poixmlDocumentPart5 = chartsMap.get("/word/charts/chart6.xml");
            new PoiWordTools().replaceCombinationCharts(poixmlDocumentPart5, titleArr, fldNameArr, listItemsByType);
        }
    
    }
    
    
    

    类2:PoiWordTools

    package com.example.demo.util;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.math.BigDecimal;
    import java.math.BigInteger;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.poi.ooxml.POIXMLDocumentPart;
    import org.apache.poi.ss.usermodel.*;
    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.XWPFTableCell;
    import org.openxmlformats.schemas.drawingml.x2006.chart.*;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTColor;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTParaRPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTShd;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalJc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
    
    /**
     * poi生成word的工具类
     * 针对于模板中的图表是静态的,也就是模板中的图表长什么样子不会根据数据而改变
     */
    public class PoiWordTools {
    
        private static final BigDecimal bd2 = new BigDecimal("2");
    
    
        /**
         * 调用替换柱状图数据
         */
        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数据
            new PoiWordTools().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数据
            new PoiWordTools().refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据
            new PoiWordTools().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数据
            new PoiWordTools().refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据
            new PoiWordTools().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数据
            new PoiWordTools().refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据   数据中下标1开始的是柱状图数据,所以这个是1
            refreshBarStrGraphContent(barChart, barSerList, listItemsByType, fldNameArr, 1);
    
    
            CTLineChart lineChart = plotArea.getLineChartArray(0);
            List<CTLineSer> lineSerList = lineChart.getSerList();   // 获取折线图单位
            //刷新内置excel数据   有一个就可以了    有一个就可以了    有一个就可以了
            //new PoiWordTools().refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据   数据中下标3开始的是折线图的数据,所以这个是3
            new PoiWordTools().refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, 3);
    
        }
    
    
        /**
         * 刷新折线图数据方法
         *
         * @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
            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;
        }
    
    
        /**
         * 设置表格样式
         *
         * @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结束---
        }
    
    
        /**
         * 获取内置表格数据,拿到第一行第一列格子数据
         * 有时候模板设计太复杂,对于图表不能精准定位,可以通过设置图表表格数据的第一行第一列格子数据来区分,这个数据不影响图表显示,所以用来区分每个图表
         */
        public static String getZeroData(POIXMLDocumentPart poixmlDocumentPart){
            String text = "";
            try {
                XWPFChart chart = (XWPFChart) poixmlDocumentPart;
                chart.getCTChart();
    
                POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
                InputStream xlsin = xlsPart.getPackagePart().getInputStream();
    
                Workbook workbook = new XSSFWorkbook(xlsin);
                // 获取第一个sheet
                Sheet sheet = workbook.getSheetAt(0);
                // 第一行
                Row row = sheet.getRow(0);
                // 第一列
                Cell cell = row.getCell(0);
    
                cell.setCellType(CellType.STRING);  // 设置一下格子类型为字符串,不然如果是数字或者时间的话,获取很麻烦
                text = cell.getStringCellValue();   // 获取格子内容
    
                System.out.println("(0,0)格子值:" + text);
    
                // 关闭流
                xlsin.close();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    
            return text;
        }
    
    
    }
    
    

    4.直接运行PoiDemoWordTable类中的main方法即可

    该示例中,实现了:文本替换、动态添加表格、柱状图、折线图、饼图、柱状+折线组合图,后续有其它的示例,会继续在此基础上扩展。代码都很简单。

    5.运行结果

    有个问题(已解决):运行代码之后查看生成的word结果,发现可能部分图表显示数据和实际代码中设置的数据不一致,这种情况都是word模板引起的。
    比方说在这个图中只显示了一条折线图,但是实际上代码数据中有3个折线图数据;这里我们右键该图表:点击编辑数据,然后会出来一个excel表格,这就是图表内置的数据,打开后我们可以看到一个蓝色的框框:,这个蓝色框框包含的数据,图表才会显示,这里是图表真正的数据源;对于这种情况,需要手动的把所有数据被蓝色框框包住才行,直接鼠标托就行。

    对于这个问题,word应该是有办法解决的,也就是图表的数据源能够动态更新,这个有需要的童鞋可以研究下。

     

    2019-12-04:新增:动态刷新内置Excel数据

    1:在原有模板的基础上,新加内置Excel表格文件,如图所示:图片看得清哈......

    说明:尝试过使用xlsx后缀的文件,但是代码报错了,报错大概意思是:你确定这是个excel文件?

    所以改成xls就好了,至于xlsx为什么不行,下来继续琢磨;

     

    2:一个类代码

    该类是在原有的demo代码里面写的,只有一个类,和之前的不冲突,但是用的word模板是同一个;

    看着不明白的地方,多瞅瞅,欢迎提出,我也是看的官网来着;

    /**
     * 代码参考了poi官网文档的api示例
     * poi官方api:http://poi.apache.org/components/document/quick-guide-xwpf.html
     * 官方示例源码:http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/UpdateEmbeddedDoc.java
     */
    package com.example.demo;
    
    
    import org.apache.poi.openxml4j.opc.PackagePart;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * 更新模板word中的内置Excel数据
     * 代码参考了poi官网文档的api示例
     * poi官方api:http://poi.apache.org/components/document/quick-guide-xwpf.html
     * 官方示例源码:http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/UpdateEmbeddedDoc.java
     */
    public class UpdateEmbeddedDoc {
    
        private static final String templateurl = "D:\\youxi\\jx\\test.docx";  // 模板文件
        private static final String returnurl = "D:\\youxi\\jx\\result.docx";  // 结果文件
        private XWPFDocument doc; // 模板文档对象
        private File docFile;
        private static final int SHEET_NUM = 0;   // xls中的sheet页数
        private static List<Map<String, String>> dataList = new ArrayList<Map<String, String>>();   // 模拟数据
    
        static {
            // 模拟数据
            for (int i = 0; i < 10; i++) {
                Map<String, String> map = new HashMap<String, String>();
                map.put("index-0", "老王吧" + i);
                map.put("index-1", "老李吧" + i);
                map.put("index-2", "老张吧" + i);
                map.put("index-3", "老刘吧" + i);
                map.put("index-4", "老杨吧" + i);
                map.put("index-5", "老乌龟吧" + i);
    
                dataList.add(map);
            }
        }
    
    
        public static void main(String[] args) throws Exception {
            UpdateEmbeddedDoc ued = new UpdateEmbeddedDoc(templateurl);
            ued.updateEmbeddedDoc();
        }
    
        /**
         * 构造函数,加载模板文档
         * @param filename
         * @throws IOException
         */
        public UpdateEmbeddedDoc(String filename) throws IOException {
            this.docFile = new File(filename);
            if (!this.docFile.exists()) {
                throw new FileNotFoundException("The Word document " + filename + " does not exist.");
            }
            try (FileInputStream fis = new FileInputStream(this.docFile)) {
                // Open the Word document file and instantiate the XWPFDocument class.
                this.doc = new XWPFDocument(fis);
            }
        }
    
    
        /**
         * 更新word文档中内置的Excel工作簿
         * Excel是事先已知的,并且在模板word中已经插入成功了的
         * @param filename
         * @throws IOException
         */
        public void updateEmbeddedDoc() throws Exception {
            // 获取模板文档中的内置部分,也就是获取到插入的Excel文档集合
            List<PackagePart> embeddedDocs = this.doc.getAllEmbeddedParts();
            for (PackagePart pPart : embeddedDocs) {
    
                // 这里打印出来文档中所有的内置对象,可以看到每个内置对象都有一个唯一标识,通过这个标识可以做相应的业务逻辑;
                // 这里打印的oleFlag可能因为机器环境原因有所不同,建议先打印出oleFlag的值,对比后再做if判断;
                // 反正这里输出的内容看一下,就明白了;
                String oleFlag = pPart.toString();
                System.out.println(oleFlag);
    
                // 记得if中的条件“oleObject1”要和上面的oleFlag对比一下,能够唯一标识就好,我不敢保证每台机器的值都是“oleObject1”
                // 第一个内置对象,
                if (oleFlag.indexOf("oleObject1") > 0) {
                    doXls1(pPart);
    
                } else if (oleFlag.indexOf("oleObject2") > 0) {
                    doXls2(pPart); // 第二个内置对象,
    
                } else if (oleFlag.indexOf("oleObject3") > 0) {
                    doXls3(pPart); // 第三个内置对象,
    
                }
    
                // TODO.......
    
            }
    
            if (!embeddedDocs.isEmpty()) {
                // Finally, write the newly modified Word document out to file.
                try (FileOutputStream fos = new FileOutputStream(returnurl)) {
                    File file = new File(returnurl);
                    if (file.exists()) {
                        file.delete();
                    }
                    this.doc.write(fos);
                    fos.close();
                }
            }
        }
    
    
        /**
         * 第一个内置对象,数据的话自己造吧,这里我懒,用了一个数据
         * @param pPart
         * @throws Exception
         */
        public void doXls1(PackagePart pPart) throws Exception {
            try (InputStream is = pPart.getInputStream();
                 Workbook workbook = WorkbookFactory.create(is);
                 OutputStream os = pPart.getOutputStream()) {
                Sheet sheet = workbook.getSheetAt(SHEET_NUM);
                int ROW_NUM = 1;
                // 设置内置xlsx文件的数据,这里示例代码写的很傻瓜,看明白就好了;
                for (int i = 0; i < dataList.size(); i++) {
                    Row row = sheet.createRow(ROW_NUM); // 创建行
    
                    Map<String, String> colMap = dataList.get(i);
                    Cell cell0 = row.createCell(0);
                    cell0.setCellValue(colMap.get("index-0")); // 第0列数据
    
                    Cell cell1 = row.createCell(1);
                    cell1.setCellValue(colMap.get("index-1")); // 第1列数据
    
                    Cell cell2 = row.createCell(2);
                    cell2.setCellValue(colMap.get("index-2")); // 第2列数据
    
                    Cell cell3 = row.createCell(3);
                    cell3.setCellValue(colMap.get("index-3")); // 第3列数据
    
                    Cell cell4 = row.createCell(4);
                    cell4.setCellValue(colMap.get("index-4")); // 第4列数据
    
                    Cell cell5 = row.createCell(5);
                    cell5.setCellValue(colMap.get("index-5")); // 第5列数据
    
    
                    ROW_NUM++;
                }
    
                workbook.write(os);
            }
        }
    
    
        /**
         * 第二个内置对象,数据的话自己造吧,这里我懒,用了一个数据
         * @param pPart
         * @throws Exception
         */
        public void doXls2(PackagePart pPart) throws Exception {
            try (InputStream is = pPart.getInputStream();
                 Workbook workbook = WorkbookFactory.create(is);
                 OutputStream os = pPart.getOutputStream()) {
                Sheet sheet = workbook.getSheetAt(SHEET_NUM);
                int ROW_NUM = 1;
                // 设置内置xlsx文件的数据,这里示例代码写的很傻瓜,看明白就好了;
                for (int i = 0; i < dataList.size(); i++) {
                    Row row = sheet.createRow(ROW_NUM); // 创建行
    
                    Map<String, String> colMap = dataList.get(i);
                    Cell cell0 = row.createCell(0);
                    cell0.setCellValue(colMap.get("index-0")); // 第0列数据
    
                    Cell cell1 = row.createCell(1);
                    cell1.setCellValue(colMap.get("index-1")); // 第1列数据
    
                    Cell cell2 = row.createCell(2);
                    cell2.setCellValue(colMap.get("index-2")); // 第2列数据
    
                    Cell cell3 = row.createCell(3);
                    cell3.setCellValue(colMap.get("index-3")); // 第3列数据
    
                    Cell cell4 = row.createCell(4);
                    cell4.setCellValue(colMap.get("index-4")); // 第4列数据
    
                    Cell cell5 = row.createCell(5);
                    cell5.setCellValue(colMap.get("index-5")); // 第5列数据
    
    
                    ROW_NUM++;
                }
    
                workbook.write(os);
            }
        }
    
    
        /**
         * 第三个内置对象,数据的话自己造吧,这里我懒,用了一个数据
         * @param pPart
         * @throws Exception
         */
        public void doXls3(PackagePart pPart) throws Exception {
            try (InputStream is = pPart.getInputStream();
                 Workbook workbook = WorkbookFactory.create(is);
                 OutputStream os = pPart.getOutputStream()) {
                Sheet sheet = workbook.getSheetAt(SHEET_NUM);
                int ROW_NUM = 1;
                // 设置内置xlsx文件的数据,这里示例代码写的很傻瓜,看明白就好了;
                for (int i = 0; i < dataList.size(); i++) {
                    Row row = sheet.createRow(ROW_NUM); // 创建行
    
                    Map<String, String> colMap = dataList.get(i);
                    Cell cell0 = row.createCell(0);
                    cell0.setCellValue(colMap.get("index-0")); // 第0列数据
    
                    Cell cell1 = row.createCell(1);
                    cell1.setCellValue(colMap.get("index-1")); // 第1列数据
    
                    Cell cell2 = row.createCell(2);
                    cell2.setCellValue(colMap.get("index-2")); // 第2列数据
    
                    Cell cell3 = row.createCell(3);
                    cell3.setCellValue(colMap.get("index-3")); // 第3列数据
    
                    Cell cell4 = row.createCell(4);
                    cell4.setCellValue(colMap.get("index-4")); // 第4列数据
    
                    Cell cell5 = row.createCell(5);
                    cell5.setCellValue(colMap.get("index-5")); // 第5列数据
    
    
                    ROW_NUM++;
                }
    
                workbook.write(os);
            }
        }
    
    
    }
    

    生成结果:双击结果文档中的内置excel表格,结果如图

     

    2020-04-07:新增:更新插入的文本框内容

    1:在博友的帮助下,添加了对文本框内容的替换,方式很简单,模板截图如下:随意位置插入文本框即可

    2:主要类:
    该方法参考地址:https://blog.csdn.net/yousun4688/article/details/90108335(感谢老哥)

    package com.example.demo.text;
    
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.xmlbeans.XmlCursor;
    import org.apache.xmlbeans.XmlObject;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * 对文本框的替换,对文本框的替换,不是正常输入的文本
     */
    public class TextBox {
    
        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 main(String[] args) throws Exception {
    
            final String returnurl = "D:\\youxi\\jx\\textbox.docx";  // 结果文件
            final String templateurl = "D:\\直真科技工作相关\\demo\\src\\main\\resources\\textbox.docx";  // 模板文件
    
            InputStream is = new FileInputStream(new File(templateurl));
            XWPFDocument doc = new XWPFDocument(is);
    
            // 替换word模板数据
            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 Exception {
            doParagraphs(doc); // 处理段落文字数据,包括文字和表格、图片
        }
    
    
        /**
         * 处理段落文字
         *
         * @param doc
         * @throws InvalidFormatException
         * @throws FileNotFoundException
         * @throws IOException
         */
        public static void doParagraphs(XWPFDocument doc) throws Exception {
    
            // 文本数据
            Map<String, String> textMap = new HashMap<String, String>();
            textMap.put("texttext", "我是被替换的普通文本内容");
            textMap.put("name", "我是被替换的文本框内容");
            textMap.put("zuoyou", "左右");
    
            changeTextBox(doc, textMap);
    
        }
    
    
        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) {
            for (int i = 0; i < 10; i++) {
                if (cursor.toChild(i)) {
                    if (cursor.getDomNode().getNodeName().equals(patternList.get(start))) {
                        if (start == patternList.size() - 1) {
                            String reString = cursor.getTextValue();
                            System.out.println(reString);
                            reString = reString.replaceAll("\\{\\{", "").replaceAll("}}", "");
    
                            for (String e : map.keySet()) {
                                if (reString.equals(e)) {
                                    //    执行替换
                                    reString = reString.replaceAll(e, map.get(e));
                                }
                            }
                            cursor.setTextValue(reString);
                        }
                        eachchild(cursor, start + 1, map);
                    } else {
                        cursor.toParent();
                    }
                }
            }
    
            cursor.toParent();
        }
    
    
    }
    

    3:替换后的效果,这个方法对普通文本不会生效,只会对文本框有效,并且替换的逻辑可以自己控制

     

    2020-04-10:新增:新增一个定位图表的方式

    问题描述:

    在使用word模板中,如果存在很多个图表,如何获取到正确的图表,按照我现有的方式是如图这样。

    通过把图表对象toString后获得“/word/charts/chart1.xml”这样的key值,这种方式对于图表在word模板中的位置是从上到下的很好用。

    但是如果现在word模板中的图表位置很乱,位置是随意插入的,有横着排,也有竖着排,布局很乱的情况,这种方式就不好用了。

    1:解决方案

    对图表编辑数据的表格进行了观察,发现第一行第一列数据,无论怎样设置都不会推图表显示有任何影响,如下图所示的这个格子数据。所以在word模板中,修改每个图表的这个格子数据,保证全局唯一,相当于图表的唯一标识。然后在读取word模板时,读取一下图表的数据,获取第一行第一列格子的值,用来当作key。

    2:修改模板

    右键图表,选择编辑数据,出来的表格,修改第一行第一列的数据,要求全局唯一不重复。然后保存。

    3:新增处理方法

    该方法拿到POIXMLDocumentPart 对象,拿到Workbook对象,返回的text就是第一行第一列的数据。

    /**
         * 获取内置表格数据,拿到第一行第一列格子数据
         * 有时候模板设计太复杂,对于图表不能精准定位,可以通过设置图表表格数据的第一行第一列格子数据来区分,这个数据不影响图表显示,所以用来区分每个图表
         */
        public static String getZeroData(POIXMLDocumentPart poixmlDocumentPart){
            String text = "";
            try {
                XWPFChart chart = (XWPFChart) poixmlDocumentPart;
                chart.getCTChart();
    
                POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
                InputStream xlsin = xlsPart.getPackagePart().getInputStream();
    
                Workbook workbook = new XSSFWorkbook(xlsin);
                // 获取第一个sheet
                Sheet sheet = workbook.getSheetAt(0);
                // 第一行
                Row row = sheet.getRow(0);
                // 第一列
                Cell cell = row.getCell(0);
    
                cell.setCellType(CellType.STRING);  // 设置一下格子类型为字符串,不然如果是数字或者时间的话,获取很麻烦
                text = cell.getStringCellValue();   // 获取格子内容
    
                System.out.println("(0,0)格子值:" + text);
    
                // 关闭流
                xlsin.close();
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    
            return text;
        }

     4:设置key

    5:通过key获取图表对象

     

    6:代码对应类:com.example.demo.example.barchart.BarChart

     

    2020-04-11:新增:柱状图动态列,解决需要对图表编辑数据才能有效显示的问题

    1:主类

    package com.example.demo.example.barchart;
    
    import com.example.demo.util.PoiWordTools;
    import com.example.demo.util.PoiWordToolsDynamic;
    import org.apache.poi.ooxml.POIXMLDocumentPart;
    import org.apache.poi.xwpf.usermodel.XWPFChart;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    
    /**
     * 动态的柱状图,也就是列不确定,由数据决定
     * 示例代码仅提供实现的参考,可根据自己的业务修改逻辑
     */
    public class BarChartDynamic {
    
        public static void main(String[] args) throws Exception {
    
            final String returnurl = "D:\\youxi\\jx\\barchartdynamicresult.docx";  // 结果文件
            final String templateurl = "D:\\直真科技工作相关\\demo\\src\\main\\resources\\barchartdynamic.docx";  // 模板文件
    
            InputStream is = new FileInputStream(new File(templateurl));
            XWPFDocument doc = new XWPFDocument(is);
    
            // 替换word模板数据
            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 Exception {
            doCharts(doc);  // 处理图表数据,柱状图
        }
    
    
        /**
         * 处理图表
         *
         * @param doc
         * @throws FileNotFoundException
         */
        public static void doCharts(XWPFDocument doc) throws FileNotFoundException {
            /**----------------------------处理图表------------------------------------**/
            // 获取word模板中的所有图表元素,用map存放
            // 为什么不用list保存:查看doc.getRelations()的源码可知,源码中使用了hashMap读取文档图表元素,
            // 对relations变量进行打印后发现,图表顺序和文档中的顺序不一致,也就是说relations的图表顺序不是文档中从上到下的顺序
            Map<String, POIXMLDocumentPart> chartsMap = new HashMap<String, POIXMLDocumentPart>();
            //动态刷新图表
            List<POIXMLDocumentPart> relations = doc.getRelations();
            for (POIXMLDocumentPart poixmlDocumentPart : relations) {
                if (poixmlDocumentPart instanceof XWPFChart) {  // 如果是图表元素
    
                    // 获取图表对应的表格数据里面的第一行第一列数据,可以拿来当作key值
                    String key = new PoiWordTools().getZeroData(poixmlDocumentPart).trim();
    
                    System.out.println("key:" + key);
    
                    chartsMap.put(key, poixmlDocumentPart);
                }
            }
    
            System.out.println("\n图表数量:" + chartsMap.size() + "\n");
    
            // 第一个图表-柱状图
            doCharts1(chartsMap);
    
        }
    
    
        /**
         * 封装图表数据
         * @param chartsMap
         */
        public static void doCharts1(Map<String, POIXMLDocumentPart> chartsMap) {
            // 数据准备
            List<String> titleArr = new ArrayList<String>();// 标题,也就是对图表选择编辑数据后显示的表格数据的第一行
            titleArr.add("");
            titleArr.add("存款$");
            titleArr.add("欠款$");
            titleArr.add("还款$");
    
            List<String> fldNameArr = new ArrayList<String>();// 字段名(数据有多少列,就多少个)
            fldNameArr.add("item1");
            fldNameArr.add("item2");
            fldNameArr.add("item3");
            fldNameArr.add("item4");
    
            // 数据集合
            List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
    
            // 数据的话随便整都行
    
            // 第一行数据
            Map<String, String> base1 = new HashMap<String, String>();
            base1.put("item1", "2020-05");
            base1.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base1.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base1.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第二行数据
            Map<String, String> base2 = new HashMap<String, String>();
            base2.put("item1", "2020-06");
            base2.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base2.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base2.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            // 第三行数据
            Map<String, String> base3 = new HashMap<String, String>();
            base3.put("item1", "2020-07");
            base3.put("item2", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base3.put("item3", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
            base3.put("item4", (int)(1 + Math.random() * (100 - 1 + 1)) + "");
    
            listItemsByType.add(base1);
            listItemsByType.add(base2);
            listItemsByType.add(base3);
    
            // 注意这里的key值
            POIXMLDocumentPart poixmlDocumentPart = chartsMap.get("嘻嘻嘻嘻");  // 图表对象
            new PoiWordToolsDynamic().replaceBarCharts(poixmlDocumentPart, titleArr, fldNameArr, listItemsByType);
        }
    
    
    }
    
    

    2:辅助类1

    package com.example.demo.util;
    
    import org.apache.poi.ooxml.POIXMLDocumentPart;
    import org.apache.poi.ss.usermodel.*;
    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.XWPFTableCell;
    import org.openxmlformats.schemas.drawingml.x2006.chart.*;
    import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
    import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.math.BigDecimal;
    import java.math.BigInteger;
    import java.util.List;
    import java.util.Map;
    
    /**
     * poi生成word的工具类
     * 可以动态生成图表,可以自己设置图表列的数量
     */
    public class PoiWordToolsDynamic {
    
        private static final BigDecimal bd2 = new BigDecimal("2");
    
    
        /**
         * 调用替换柱状图数据-可以实现动态列
         * 其它的折线图、饼图大同小异
         */
        public static void replaceBarCharts(POIXMLDocumentPart poixmlDocumentPart,
                                            List<String> titleArr,
                                            List<String> fldNameArr,
                                            List<Map<String, String>> listItemsByType) {
    
            // 很重要的参数,图表系列的数量,由这里的数据决定
            int culomnNum = titleArr.size() - 1;
    
            XWPFChart chart = (XWPFChart) poixmlDocumentPart;
            chart.getCTChart();
    
            //根据属性第一列名称切换数据类型
            CTChart ctChart = chart.getCTChart();
            CTPlotArea plotArea = ctChart.getPlotArea();
    
            // 柱状图用plotArea.getBarChartArray,
            // 折线图用plotArea.getLineChartArray,
            // 饼图用plotArea.getPieChartArray.....
            // 还有很多其它的
            CTBarChart barChart = plotArea.getBarChartArray(0);
    
            // 清除图表的样式,由代码自己设置
            barChart.getSerList().clear();
    
            //刷新内置excel数据
            new PoiWordToolsDynamic().refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据-也就是刷新图表的数据源范围
            refreshBarStrGraphContent(barChart, listItemsByType, fldNameArr, 1, culomnNum, titleArr);
        }
    
    
        /**
         * 调用替换柱状图数据-可以实现动态列
         * 其它的折线图、饼图大同小异
         */
        public static void replaceLineCharts(POIXMLDocumentPart poixmlDocumentPart,
                                             List<String> titleArr,
                                             List<String> fldNameArr,
                                             List<Map<String, String>> listItemsByType) {
    
            // 很重要的参数,图表系列的数量,由这里的数据决定
            int culomnNum = titleArr.size() - 1;
    
            XWPFChart chart = (XWPFChart) poixmlDocumentPart;
            chart.getCTChart();
    
            //根据属性第一列名称切换数据类型
            CTChart ctChart = chart.getCTChart();
            CTPlotArea plotArea = ctChart.getPlotArea();
    
            // 柱状图用plotArea.getBarChartArray,
            // 折线图用plotArea.getLineChartArray,
            // 饼图用plotArea.getPieChartArray.....
            // 还有很多其它的
            CTLineChart ctLineChart = plotArea.getLineChartArray(0);
    
            // 清除图表的样式,由代码自己设置
            ctLineChart.getSerList().clear();
    
            //刷新内置excel数据
            new PoiWordToolsDynamic().refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据-也就是刷新图表的数据源范围
            refreshLineStrGraphContent(ctLineChart, listItemsByType, fldNameArr, 1, culomnNum, titleArr);
        }
    
    
        /**
         * 动态添加列-柱状图的
         */
        public static boolean refreshBarStrGraphContent(CTBarChart barChart,
                                                        List<Map<String, String>> dataList,
                                                        List<String> fldNameArr,
                                                        int position,
                                                        int culomnNum,
                                                        List<String> titleArr) {
            boolean result = true;
            //更新数据区域
            for (int i = 0; i < culomnNum; i++) {
                CTBarSer ctBarSer = barChart.addNewSer();
                ctBarSer.addNewIdx().setVal(i);
                ctBarSer.addNewOrder().setVal(i);
    
                // 设置柱状图的系列名称
                // 设置标题 用以下这个方式,可以兼容office和wps(因为是动态添加,不可以直接get到,需要这样写)
                CTSerTx tx = ctBarSer.addNewTx();
                CTStrRef ctStrRef = tx.addNewStrRef();
                CTStrData ctStrData = ctStrRef.addNewStrCache();
                ctStrData.addNewPtCount().setVal(1);
                CTStrVal ctStrVal = ctStrData.addNewPt();
                ctStrVal.setIdx(0);
                ctStrVal.setV(titleArr.get(i + 1));  // 设置系列的名称
    
    
                // 设置柱状图系列的颜色,就是显示的柱子的颜色,不设置的话会默认都是黄色
                // 必须使用ACCENT_x系列的才行
                CTSchemeColor ctSchemeColor = ctBarSer.addNewSpPr().addNewSolidFill().addNewSchemeClr();
                ctSchemeColor.setVal(STSchemeColorValTools.get(i));
    
    
                CTAxDataSource cat = ctBarSer.addNewCat();
                CTNumDataSource val = ctBarSer.addNewVal();
    
                CTStrData strData = cat.addNewStrRef().addNewStrCache();
                CTNumData numData = val.addNewNumRef().addNewNumCache();
                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.addNewPtCount().setVal(idx);
                strData.addNewPtCount().setVal(idx);
    
    
            }
            return result;
        }
    
    
        /**
         * 动态添加列-折线图的
         */
        public static boolean refreshLineStrGraphContent(CTLineChart ctLineChart,
                                                         List<Map<String, String>> dataList,
                                                         List<String> fldNameArr,
                                                         int position,
                                                         int culomnNum,
                                                         List<String> titleArr) {
            boolean result = true;
            //更新数据区域
            for (int i = 0; i < culomnNum; i++) {
                CTLineSer ctLineSer = ctLineChart.addNewSer();
                ctLineSer.addNewIdx().setVal(i);
                ctLineSer.addNewOrder().setVal(i);
    
                // 设置柱状图的系列名称
                // 设置标题 用以下这个方式,可以兼容office和wps(因为是动态添加,不可以直接get到,需要这样写)
                CTSerTx tx = ctLineSer.addNewTx();
                CTStrRef ctStrRef = tx.addNewStrRef();
                CTStrData ctStrData = ctStrRef.addNewStrCache();
                ctStrData.addNewPtCount().setVal(1);
                CTStrVal ctStrVal = ctStrData.addNewPt();
                ctStrVal.setIdx(0);
                ctStrVal.setV(titleArr.get(i + 1));  // 设置系列的名称
    
    
    
                // 设置柱状图系列的颜色,就是显示的柱子的颜色,不设置的话会默认都是黄色
                // 必须使用ACCENT_x系列的才行
                CTSchemeColor ctSchemeColor = ctLineSer.addNewSpPr().addNewLn().addNewSolidFill().addNewSchemeClr();
                ctSchemeColor.setVal(STSchemeColorValTools.get(i));
    
    
                CTAxDataSource cat = ctLineSer.addNewCat();
                CTNumDataSource val = ctLineSer.addNewVal();
    
                CTStrData strData = cat.addNewStrRef().addNewStrCache();
                CTNumData numData = val.addNewNumRef().addNewNumCache();
                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.addNewPtCount().setVal(idx);
                strData.addNewPtCount().setVal(idx);
    
            }
            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
            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;
        }
    
    }
    

    3:辅助类2

    package com.example.demo.util;
    
    import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 官方对于颜色的解释: http://poi.apache.org/apidocs/dev/org/apache/poi/sl/draw/binding/STSchemeColorVal.html
     */
    public final class STSchemeColorValTools {
        static List<STSchemeColorVal.Enum> colorEnum = new ArrayList<>();
    
        static {
    //        colorEnum.add(STSchemeColorVal.BG_1);
    //        colorEnum.add(STSchemeColorVal.BG_2);
    //        colorEnum.add(STSchemeColorVal.TX_1);
    //        colorEnum.add(STSchemeColorVal.TX_2);
            colorEnum.add(STSchemeColorVal.ACCENT_1);
            colorEnum.add(STSchemeColorVal.ACCENT_2);
            colorEnum.add(STSchemeColorVal.ACCENT_3);
            colorEnum.add(STSchemeColorVal.ACCENT_4);
            colorEnum.add(STSchemeColorVal.ACCENT_5);
            colorEnum.add(STSchemeColorVal.ACCENT_6);
    //        colorEnum.add(STSchemeColorVal.HLINK);
    //        colorEnum.add(STSchemeColorVal.FOL_HLINK);
    //        colorEnum.add(STSchemeColorVal.PH_CLR);
    //        colorEnum.add(STSchemeColorVal.DK_1);
    //        colorEnum.add(STSchemeColorVal.DK_2);
    //        colorEnum.add(STSchemeColorVal.LT_1);
    //        colorEnum.add(STSchemeColorVal.LT_2);
        }
    
        public static STSchemeColorVal.Enum get(int i){
            return colorEnum.get(i);
        }
    }
    
    
    

    4:模板

    5:结果

    6:如果要显示数字的话,直接在模板里面设置显示就好了

     

    2020-04-21:新增:表格进行合并单元格,横竖都行,两种方式(感谢刘老师)

    场景:在word中插入表格,并对表格进行合并,这里提供两种方式,分别对应两个类

    1:模板文档内容:

    2:类1

    package com.example.demo.example.table;
    
    import com.example.demo.util.PoiWordTools;
    import org.apache.poi.ooxml.POIXMLDocumentPart;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.util.Units;
    import org.apache.poi.xwpf.usermodel.*;
    import org.apache.xmlbeans.XmlCursor;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
    import org.springframework.util.StringUtils;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * 表格
     */
    public class Table {
    
        public static void main(String[] args) throws Exception {
    
            final String returnurl = "D:\\youxi\\jx\\table1.docx";  // 结果文件
            final String templateurl = "D:\\POI\\demo\\src\\main\\resources\\table1.docx";  // 模板文件
    
            InputStream is = new FileInputStream(new File(templateurl));
            XWPFDocument doc = new XWPFDocument(is);
    
            // 替换word模板数据
            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 Exception {
            doParagraphs(doc); // 处理段落文字数据,包括文字和表格、图片
        }
    
    
        /**
         * 处理段落文字
         *
         * @param doc
         * @throws InvalidFormatException
         * @throws FileNotFoundException
         * @throws IOException
         */
        public static void doParagraphs(XWPFDocument doc) throws Exception {
            /**----------------------------处理段落------------------------------------**/
            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);// ---这个是关键
    
    
                                // 设置表格宽度,第一行宽度就可以了,这个值的单位,目前我也还不清楚,还没来得及研究
                                tableOne.setWidth(8500);
    
                                // 表格第一行,对于每个列,必须使用createCell(),而不是getCell(),因为第一行嘛,肯定是属于创建的,没有create哪里来的get呢
                                XWPFTableRow tableOneRowOne = tableOne.getRow(0);//行
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowOne.getCell(0), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "10%", "序号");
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowOne.createCell(), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "公司名称(英文)");
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowOne.createCell(), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "公司名称(中文)");
    
                                for (int i = 0; i < 10; i ++) {
                                    // 表格第二行
                                    XWPFTableRow tableOneRowTwo = tableOne.createRow();//行
                                    new PoiWordTools().setWordCellSelfStyle(tableOneRowTwo.getCell(0), "微软雅黑", "9", 0, "left", "top", "#000000", "#ffffff", "10%", "一行一列");
                                    new PoiWordTools().setWordCellSelfStyle(tableOneRowTwo.getCell(1), "微软雅黑", "9", 0, "left", "top", "#000000", "#ffffff", "45%", "一行一列");
                                    new PoiWordTools().setWordCellSelfStyle(tableOneRowTwo.getCell(2), "微软雅黑", "9", 0, "left", "top", "#000000", "#ffffff", "45%", "一行一列");
                                }
    
    
                                // 横着合并单元格  -----------------------------
                                CTHMerge cthMergeStart = CTHMerge.Factory.newInstance();
                                cthMergeStart.setVal(STMerge.RESTART);
                                CTHMerge cthMergeEnd = CTHMerge.Factory.newInstance();
                                cthMergeEnd.setVal(STMerge.CONTINUE);
                                XWPFTableCell cell71 = tableOne.getRow(6).getCell(0);  // 第7行的第1列
                                XWPFTableCell cell72 = tableOne.getRow(6).getCell(1);  // 第7行的第2列
                                XWPFTableCell cell73 = tableOne.getRow(6).getCell(2);  // 第7行的第3列
    
                                cell71.getCTTc().getTcPr().setHMerge(cthMergeStart);
                                cell72.getCTTc().getTcPr().setHMerge(cthMergeEnd);
                                cell73.getCTTc().getTcPr().setHMerge(cthMergeEnd);
    
    
                                // 竖着合并单元格   -----------------------------
                                CTVMerge vmergeStart = CTVMerge.Factory.newInstance();
                                vmergeStart.setVal(STMerge.RESTART);
                                CTVMerge vmergeEnd = CTVMerge.Factory.newInstance();
                                vmergeEnd.setVal(STMerge.CONTINUE);
                                XWPFTableCell cell1 = tableOne.getRow(1).getCell(0);  // 第2行第1列  第1行是表头
                                XWPFTableCell cell2 = tableOne.getRow(2).getCell(0);  // 第3行第1列
                                XWPFTableCell cell3 = tableOne.getRow(3).getCell(0);  // 第4行第1列
                                XWPFTableCell cell4 = tableOne.getRow(4).getCell(0);  // 第5行第1列
    
    
                                cell1.getCTTc().getTcPr().setVMerge(vmergeStart);
                                cell2.getCTTc().getTcPr().setVMerge(vmergeEnd);
                                cell3.getCTTc().getTcPr().setVMerge(vmergeEnd);
                                cell4.getCTTc().getTcPr().setVMerge(vmergeEnd);
    
    
    
                                // .......
                            }
    
                        }
                    }
                }
            }
        }
    
    
    
    }
    
    

    3:类2

    package com.example.demo.example.table;
    
    import com.example.demo.util.PoiWordTools;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.xwpf.usermodel.*;
    import org.apache.xmlbeans.XmlCursor;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
    
    import java.io.*;
    import java.util.List;
    
    /**
     * 表格
     */
    public class Table2 {
    
        public static void main(String[] args) throws Exception {
    
            final String returnurl = "D:\\youxi\\jx\\table1.docx";  // 结果文件
            final String templateurl = "D:\\POI\\demo\\src\\main\\resources\\table2.docx";  // 模板文件
    
            InputStream is = new FileInputStream(new File(templateurl));
            XWPFDocument doc = new XWPFDocument(is);
    
            // 替换word模板数据
            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 Exception {
            doParagraphs(doc); // 处理段落文字数据,包括文字和表格、图片
        }
    
    
        /**
         * 处理段落文字
         *
         * @param doc
         * @throws InvalidFormatException
         * @throws FileNotFoundException
         * @throws IOException
         */
        public static void doParagraphs(XWPFDocument doc) throws Exception {
            /**----------------------------处理段落------------------------------------**/
            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);// ---这个是关键
    
    
                                // 设置表格宽度,第一行宽度就可以了,这个值的单位,目前我也还不清楚,还没来得及研究
                                tableOne.setWidth(8500);
    
                                // 表格第一行,对于每个列,必须使用createCell(),而不是getCell(),因为第一行嘛,肯定是属于创建的,没有create哪里来的get呢
                                XWPFTableRow tableOneRowOne = tableOne.getRow(0);//行
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowOne.getCell(0), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "10%", "序号");
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowOne.createCell(), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "公司名称(英文)");
                                new PoiWordTools().setWordCellSelfStyle(tableOneRowOne.createCell(), "微软雅黑", "9", 0, "left", "top", "#000000", "#B4C6E7", "45%", "公司名称(中文)");
    
                                for (int i = 0; i < 10; i ++) {
                                    // 表格第二行
                                    XWPFTableRow tableOneRowTwo = tableOne.createRow();//行
                                    new PoiWordTools().setWordCellSelfStyle(tableOneRowTwo.getCell(0), "微软雅黑", "9", 0, "left", "top", "#000000", "#ffffff", "10%", "一行一列");
                                    new PoiWordTools().setWordCellSelfStyle(tableOneRowTwo.getCell(1), "微软雅黑", "9", 0, "left", "top", "#000000", "#ffffff", "45%", "一行一列");
                                    new PoiWordTools().setWordCellSelfStyle(tableOneRowTwo.getCell(2), "微软雅黑", "9", 0, "left", "top", "#000000", "#ffffff", "45%", "一行一列");
                                }
    
    
                                // 横着合并单元格  -----------------------------
                                XWPFTableCell cell71 = tableOne.getRow(6).getCell(0);  // 第7行的第1列
                                XWPFTableCell cell72 = tableOne.getRow(6).getCell(1);  // 第7行的第2列
                                XWPFTableCell cell73 = tableOne.getRow(6).getCell(2);  // 第7行的第3列
    
                                cell71.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
                                cell72.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
                                cell73.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
    
    
                                // 竖着合并单元格  -----------------------------
                                XWPFTableCell cell1 = tableOne.getRow(1).getCell(0);  // 第2行第1列  第1行是表头
                                XWPFTableCell cell2 = tableOne.getRow(2).getCell(0);  // 第3行第1列
                                XWPFTableCell cell3 = tableOne.getRow(3).getCell(0);  // 第4行第1列
                                XWPFTableCell cell4 = tableOne.getRow(4).getCell(0);  // 第5行第1列
    
                                cell1.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
                                cell2.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                                cell3.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
                                cell4.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
    
    
    
                                // .......
                            }
    
                        }
                    }
                }
            }
        }
    
    
    
    }
    
    

    4:结果:

    两种方式本质上是一样的!

     

    2020-04-23:解决问题:组合图页面显示的数据,跟第二列对应不上(感谢博友:吹古拉朽)

    事情是这样的,博客网友吹古拉朽说,组合图页面显示的数据,跟第二列对应不上,柱状图+折线图的图表,折线图会显示柱状图的数据,显示结果如下图:很明显是不对的;

     如果你已经运行过我的示例代码中的PoiDemoWordTable.java这个类,生成的第6个图表,就是这个;

    解决方案:在第六个图表对应的代码中,修改position参数的值,如图:这个参数代表数据下标,从0开始的。

     

     

    所以我这里改成3就好了。

     

    本文示例源代码:(码云地址)https://gitee.com/loverer/poi-demo

     

    展开全文
  • Aspose.cell 生成折线图

    千次阅读 2018-08-02 19:27:34
    网上找了很多资料但是...首先引用命名空间 这里要注意了 Aspose.Cell 有正版的这个要收费的,也有一大把破解版的 using Aspose.Cells; using Aspose.Cells.Charts; Excel 方法 public ActionResult Excels...

    网上找了很多资料但是发现不行 老是报错,所以自己苦心研究,终于没毛病

    废话不多说 直接上代码

    首先引用命名空间 在这里要注意了 Aspose.Cell 有正版的这个要收费的,也有一大把破解版的

    using Aspose.Cells;
    using Aspose.Cells.Charts;

    Excel 方法

    public ActionResult Excels()
    {
    WorkbookDesigner designer = new WorkbookDesigner();
    string Template_File_Path = Server.MapPath("/Feil/模板.xlsx");
    
    FileStream fileStream = new FileStream(Template_File_Path, FileMode.Open, FileAccess.Read, FileShare.Read);
    //designer.Workbook = new Workbook(fileStream);
    //WorksheetCollection worksheets = designer.Workbook.Worksheets;
    
     Workbook workbook = new Workbook(fileStream);
     Worksheet sheet = workbook.Worksheets[0]; //第一个工作表 
    Cells cells = sheet.Cells;//单元格
    //这里定义的是横坐标  通常我们叫做x轴
     string[] listsum = new string[] { "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010" };
     //以下两个数组是我们要使用的数据
    int[] str2sum = new int[] { 1, 2, 3, 5, 6, 2, 4, 3, 5, 1 };
    int[] str3sum = new int[] { 5, 2, 1, 5, 6,7,2, 3,1, 3 };
    //定义样式  后面可调用
    Aspose.Cells.Style style = new Aspose.Cells.Style();
    style.IsLocked = true;
    style.HorizontalAlignment = TextAlignmentType.Center;//文字居中  
    style.Font.Name = "宋体";//文字字体 
    style.Font.Size = 12;//文字大小 
    style.Borders[Aspose.Cells.BorderType.LeftBorder].LineStyle = CellBorderType.Thin; //应用边界线 左边界线  
    style.Borders[Aspose.Cells.BorderType.RightBorder].LineStyle = CellBorderType.Thin; //应用边界线 右边界线  
    style.Borders[Aspose.Cells.BorderType.TopBorder].LineStyle = CellBorderType.Thin; //应用边界线 上边界线  
    style.Borders[Aspose.Cells.BorderType.BottomBorder].LineStyle = CellBorderType.Thin; //应用边界线 下边界线 
    
    
    for (int i = 0; i < listsum.Length; i++)
       {
       //由于项目的需要   根据每个人的需要走  Cells[0,0] 代表的就是第一行第一个单元格 celis[0,1] 代表的就是第一行第二个单元格 以此类推  cells[2,0] 就是第三行第一个单元格
           cells[0, i+1].PutValue(listsum[i]);
           cells[0, 0].SetStyle(style);//这个主要是给第一行第一列单元格加样式
           cells[0, i+1].SetStyle(style);
           cells.SetColumnWidthPixel(3, 69);
       }
       //复制第二行数据
    for (int i = 0; i < str2sum.Length; i++)
     {
         cells[1, 0].PutValue("观察点A");
         cells[1, 0].SetStyle(style);
         cells[1, i + 1].PutValue(str2sum[i]);
         cells[1, i + 1].SetStyle(style);
         cells.SetColumnWidthPixel(3, 69);
     }
     //赋值第三行数据
     for (int i = 0; i < str3sum.Length; i++)
     {
         cells[2, 0].PutValue("观察点B");
         cells[2, 0].SetStyle(style);
         cells[2, i + 1].PutValue(str3sum[i]);
         cells[2, i + 1].SetStyle(style);
         cells.SetColumnWidthPixel(3, 69);
     }
    
    
      //创建一个chart到页面    调用CreateStaticReport2()方法
      CreateStaticReport2(workbook);
      designer.Process();
    
    
    
    System.IO.MemoryStream ms = workbook.SaveToStream();//生成数据流 
    byte[] bt = ms.ToArray();
    string fileName = "自动化监测表" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";//客户端保存的文件名 
    //以字符流的形式下载文件  
    Response.ContentType = "application/vnd.ms-excel";
    //通知浏览器下载文件而不是打开
    Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
    Response.BinaryWrite(bt);
    Response.Flush();
    Response.End();
    //return View("getexcel");
    
    }

    曲线图方法

    private void CreateStaticReport2(Workbook workbook)
     {
         //创建一个折线图                  后面的112510都是设置char图的                  
       workbook.Worksheets[0].Charts.Add(ChartType.Line, 1, 1, 25, 10);
         Aspose.Cells.Charts.Chart chart = workbook.Worksheets[0].Charts[0];
    
         //折线区域竖线设置为显示颜色设置为灰色
         chart.CategoryAxis.MajorGridLines.IsVisible = true;
         chart.CategoryAxis.MajorGridLines.Color = Color.Gray;
         //折线区域设置横着的网格线显示          
         //chart.CategoryAxis.MajorTickMark;
         //chart.CategoryAxis.MajorGridLines.Color = Color.Gray;
    
         //设置title样式
         chart.Title.Text = "自动化监测折线表-1";
         chart.Title.TextFont.Color = Color.Gray;
         chart.Title.TextFont.IsBold = true;
         chart.Title.TextFont.Size = 12;
    
    
         Cells cells = workbook.Worksheets[0].Cells;
    
         //Set Properties of nseries控制折线有多长 控制系列显示多少 
         //注意:这里的A2:F2代表什么Excel你仔细点就会发现第一列是A,第2列是B,所以在这里一定要注意
         chart.NSeries.Add("Sheet1!A2:F" +Convert.ToInt32(cells.Rows.Count) + "", false);
    
         //Set NSeries Category Datasource
         chart.NSeries.CategoryData = "Sheet1!H1:F9";
    
    
         //for (int i = 0; i < cells.Rows.Count; i++)
         //{
         //    if (i == 0)
         //    {
         //        continue;
         //    }
         //    string name = cells[i, 6].Value.ToString();
         //    //设置每条折线的名称
         //    chart.NSeries[i-1].Name = name;
         //}
    
    
         //loop over the Nseriese
         for (int i = 0; i < chart.NSeries.Count; i++)
         {
             //设置系列的名称
             chart.NSeries[i].Name = cells[i + 1, 0].Value.ToString();
             chart.NSeries[i].MarkerStyle = ChartMarkerType.Circle;
    
             //设置线的宽度
             chart.NSeries[i].Line.Weight = WeightType.MediumLine;
    
             //设置每个值坐标点的样式
             chart.NSeries[i].MarkerStyle = ChartMarkerType.Circle;
             chart.NSeries[i].MarkerSize = 5;
             chart.NSeries[i].MarkerBackgroundColor = Color.White;
             chart.NSeries[i].MarkerForegroundColor = Color.Gray;
    
             每个折线向显示出值
             chart.NSeries[i].DataLabels.IsValueShown = false;
             chart.NSeries[i].DataLabels.TextFont.Color = Color.Gray;
    
         }
    
         //设置x轴上数据的样式为灰色
         chart.CategoryAxis.TickLabels.Font.Color = Color.Gray;
         chart.CategoryAxis.TickLabelPosition = TickLabelPositionType.NextToAxis;
    
         //设置y轴的样式
         chart.ValueAxis.TickLabelPosition = TickLabelPositionType.Low;
         chart.ValueAxis.TickLabels.Font.Color = Color.Gray;
         // chart.ValueAxis.TickLabels.TextDirection = TextDirectionType.LeftToRight;
         //设置Legend位置以及样式
         chart.Legend.Position = LegendPositionType.Bottom;
         chart.Legend.TextFont.Color = Color.Gray;
         chart.Legend.Border.Color = Color.Gray;
     }

    这里写图片描述

    在此附上Aspose.cell dl下载地址

    展开全文
  • }/*** 生成折线图*/ public void createLineChart(List>lineChartDataList, SXSSFWorkbook workbook, Drawing drawing) {for (MapresultMap : lineChartDataList) { String title= StringUtils.isEmpty(resultMap....
  • 本教程中,您将学习怎样用Python来创建专业的线形接下来的练习中,您将使用您的新技能来处理真实世界的数据集。准备好笔记本我们首先设置编码环境。import pandas as pdimport matplotlib.pyplot as plt%...
  • Numbers中有丰富的图表可供用户们选择,有的人想要了解下 Numbers怎么做折线图 。Numbers如何做折线图?小编带来了Numbers制作折线图教程,看完就知道Numbers怎么画折线图啦~Numbers制作折线图教程:点按工具栏中的 ...
  • 折线图,组合图:二_不知所终的博客-CSDN博客2.java使用poiword中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换、更新内置Excel数据、更新插入的文本框内容、合并表格单元格;...
  • 参考文章的基础上,增加了模板样例 模板样例地址 百度网盘 链接:https://pan.baidu.com/s/16qDvE2-V-tpX_bY8NNnepw 提取码:yhbd 这个必须引入poi4i.0以上版本,以验证过 完整pom.xml内容: <?xml...
  • java使用poi操作world 生成饼图,柱状图,折线图,组合图开发前准备准备模板本文可用操作组合图操作java填充数据操作maven!!!WordUtil 饼图 替换入口 开发前准备 准备模板 插入模板中对应图表 本文演示饼图 折线...
  • 通过excel复制,重新生成一个新的excel实现:import copyimport openpyxlfrom openpyxl.utils import get_column_letterpath = "数据.xlsx"save_path = "数据-复制.xlsx"wb = openpyxl.load_workbook(path)wb2 = ...
  • 很多excel用户制作表格的过程中,有时候为了更加凸显数据的走势变化,就需要用到折线图了,大多数用户使用折线图都是直接插入使用,那么怎么插入折线图呢?方法很简单,下面小编为大家带来excel插入折线图的详细...
  • 先做出柱形图,然后选择一个项目的柱形,右键-选择图表类型- 选择折线图就行了选择一个数据系列做成一种图形,比如柱型,再选择一种数据拖进图中,右键设置数据系列,改变其图表类型就OK了。先选柱状图 画出两个柱状...
  • 使用Apache poi生成excel并绘制折线统计,扇形统计功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左...
  • 如果数据量过大,还会出现提示类似“最多只能处理255项数据”的报错,而且整个折线图会崩掉,然后啥都不显示的样子。。 所以最好还是选择比较合适的展现粒度,做好pivot_table再画图会比较好。 然后还可以设置X轴和Y...
  • 一个是X轴,一个是Y轴,还有一个重要点就是标题,标题就是显示折线图里面有几条线的,比如两个标题就是里面有两个折线,三个标题就是有三个折线 步骤1:此步骤需要填写五个参数,第一个是填写声明的数据变量,后面四...
  • pom: poi:用于操作Excel jfreechart:用于生产图表图片 实例: /** * 生成图表图片,并填充到xls文件... // 第一步,使用JFreeChart生成折线图的图片 // 图表标题、图表x轴名称、图表y轴名称 String title ...
  • 如何将Excel表格中插入的折线图中的圆圈设置为方块或三角形腾讯视频/爱奇艺/优酷/外卖 充值4折起我们Excel表格中,经常需要插入图表,而在折线图中,数据标记默认以圆圈显示,今天就跟大家介绍一下如何将Excel表格...
  • 下面我们就来看看详细的教程,使用excel制作折线图,单纯的插入折线图显得非常枯燥,那么如何进行调整制作出炫酷的折线图呢?现在就把制作的过程和截图分享出来,希望对你有所帮助和启发。1、首先启动excel2010,...
  • Excel通过poi设置折线图样式

    千次阅读 2020-11-23 16:59:51
    最近通过poi实现了一整套由 07版excel生成折线图、柱状图及混合双轴图形,本文将记录折线图中的关于图例、标题、坐标轴的各种样式。其中包括颜色、字体、粗细、虚实等。直接上代码吧 package ...
  • C#绘制表格与折线图

    千次阅读 2015-07-08 15:55:55
    做过一个用折线图实时展示温度,脉搏数据的功能,现在将折线图绘制相关的东西总结下。 效果图一: 效果图二: 数据是随机生成的,随着数据增加,折线会向左移动......... 主要参数设置: public void init_...
  • 每一个java屌丝程序员都应该了解,jxl可以向excel单元格中添加数据,但是可以生成非常常用的折线表吗(通俗一点就是屌丝小学时候学的有x轴y轴,还有各种坐标点...所谓模板方法是首先office工具中生成折线图,然后...
  • wps word如何绘制一有一条线的折线图

    千次阅读 2021-01-12 16:24:01
    wps word如何绘制一有一条线的折线图今天,小编给大家介绍WPS Word文档中插入制作折线图的方法,希望对大家有所帮助。具体如下:1. 首先,请大家自己的手机中找到【WPS】图标,点击进入主界面,然后选择最上面的...
  • 【Excel如何制作小微型的迷你?】谢谢邀请。我是汤帅,一个PPT自由设计师,承接PPT定制。看着歪果仁的Excel展示都是很高大上,特别是他们设计的数据与图表恰到好处,其实最终能总结的一个原因就是走心。我们既是...
  • 示例:散点最常见的散点之一是x-y散点。下面的代码会大致告诉你一个matplotlib是如何工作的,你会看到如何一点点建立起一个散点。我们正在使用点的x和y位置的一些构成数据。运行下面的代码,然后我们将解释...
  • 我们写论文或者做一些PPT的时候,经常会需要画可视化折线图,虽然网上有很多可以制作折线图的可视化工具,但是大多都加了水印或者不够方便使用,直接用别人带水印的图显然是不行的。自己画的话又不会怎么办? 以...
  • POI Word 图表、柱状图、条形图、折线图、饼图

    千次阅读 热门讨论 2020-04-22 23:03:25
    /** * poi Word生成图表-折线图 */ public class CreateWordXDDFChart2 { public static void main(String[] args) throws Exception { try (XWPFDocument document = new XWPFDocument()) { // create the ...
  • java代码取出EXCEL表数据并画折线图

    千次阅读 2017-09-26 11:28:19
    前言: 上篇文章已经介绍了,如何获取Android客户端性能:...接下来简单分享下如何将获取到的数据从EXCEL中取出并绘制折线图。 一、读取EXCEL中的数据 //获取表格数据 @SuppressWarnings("unused") private S
  • poi终于支持Word中动态刷新图表了 poi版本 1.maven坐标 org.apache.poi poi 4.1.0 org.apache.poi poi-ooxml 4.1.0
  • echarts画折线图和数据excel导出

    千次阅读 2019-11-01 15:45:31
    最近一直使用echarts画折线图此做个记录 最后样式 代码 <!DOCTYPE html> <html style="height: 100%"> <head> <meta charset="utf-8"> <script src=...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,626
精华内容 1,050
关键字:

在单元格生成折线图