java实现echart图表,table写入到Word

封装一个工具类

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDLbls;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author fax
 * @date 2021-08-23 11:08
 */
public class WordUtils {

    /**
     * 替换文档中的内容
     *
     * @param doc    Word的文档
     * @param params 待填充的数据
     *               params.put("key",value) 文档中对应为 ${key}
     */
    public void replaceInPara(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        while (iterator.hasNext()) {
            replaceInPara(iterator.next(), params);
        }
    }


    /**
     * 遍历所有表格,替换表格里面的变量
     *
     * @param doc    要替换的文档
     * @param params 参数
     */
    public void replaceInAllTable(XWPFDocument doc, Map<String, Object> params) {
        Iterator<XWPFTable> iterator = doc.getTablesIterator();
        while (iterator.hasNext()) {
            replaceInTable(iterator.next(), params);
        }
    }

    /**
     * 替换指定表格中的变量
     *
     * @param doc
     * @param tabIndex 表格下标
     * @param params   替换参数
     */
    public void replaceInTable(XWPFDocument doc, int[] tabIndex, Map<String, Object> params) {
        List<XWPFTable> tables = doc.getTables();
        for (int index : tabIndex) {
            replaceInTable(tables.get(index), params);
        }
    }

    /**
     * 替换表格中的变量
     *
     * @param table
     * @param params
     */
    public void replaceInTable(XWPFTable table, Map<String, Object> params) {
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;
        //判断表格中是否有 ${} 有就表示需要替换值
        if (matcher(table.getText()).find()) {
            rows = table.getRows();
            for (XWPFTableRow row : rows) {
                cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    paras = cell.getParagraphs();
                    for (XWPFParagraph para : paras) {
                        replaceInPara(para, params);
                    }
                }
            }
        }
    }

    /**
     * 在表格中新增行数并填充数据
     *
     * @param table    需要插入数据的表格
     * @param rowDatas 插入数据集合(注:填充的数据要与单元格的数量保持一致)
     */
    public void insertTableRow(XWPFTable table, List<String[]> rowDatas) {
        for (String[] cellDatas : rowDatas) {
            XWPFTableRow row = table.createRow();
            List<XWPFTableCell> cells = row.getTableCells();
            for (int j = 0; j < cells.size(); j++) {
                cells.get(j).setText(cellDatas[j]);
            }
        }
    }

    /**
     * 替换段落里面的变量
     *
     * @param para   要替换的段落
     * @param params 参数
     */
    private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
        List<XWPFRun> runs;
        StringBuilder runText = new StringBuilder();

        if (matcher(para.getParagraphText()).find()) {
            runs = para.getRuns();
            int j = runs.size();
            for (int i = 0; i < j; i++) {
                runText.append(runs.get(0).toString());
                //保留最后一个段落,在这段落中替换值,保留原有段落样式
                if (!((j - 1) == i)) {
                    para.removeRun(0);
                }
            }
            String text = runText.toString();
            Matcher matcher;
            while ((matcher = matcher(text)).find()) {
                text = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
            }
            runs.get(0).setText(text, 0);

        }
    }

    /**
     * 创建标题
     *
     * @param paragraph
     * @param data
     */
    public void createTitle(XWPFParagraph paragraph, String data) {
        XWPFRun createRun = paragraph.insertNewRun(0);
        createRun.setText(data);
        createRun.setFontFamily("宋体");
        createRun.setFontSize(14);
        createRun.setBold(true);
        paragraph.setSpacingAfter(10);
        paragraph.setSpacingBefore(10);
        //对齐方式
        paragraph.setAlignment(ParagraphAlignment.LEFT);
    }

    /**
     * 创建段落
     *
     * @param paragraph
     * @param data
     */
    public void createParagraph(XWPFParagraph paragraph, String data) {
        XWPFRun createRun = paragraph.createRun();
        createRun.setText(data);
        createRun.setFontFamily("宋体");
        createRun.setFontSize(12);

        paragraph.setFirstLineIndent(20);
        paragraph.setAlignment(ParagraphAlignment.BOTH);
        paragraph.setIndentationFirstLine(600);
        paragraph.setSpacingAfter(10);
        paragraph.setSpacingBefore(10);
    }

    /**
     * 创建表格
     *
     * @param document
     * @param tableList
     */
    public void createTable(XWPFDocument document, List<String[]> tableList) {
        XWPFTable table = document.createTable(tableList.size(), tableList.get(0).length);
        //设置表格的宽度
        CTTblWidth comTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
        comTableWidth.setType(STTblWidth.PCT);
        comTableWidth.setW(BigInteger.valueOf(5000));

        // 填充数据
        int length = tableList.size();
        for (int i = 0; i < length; i++) {
            XWPFTableRow row = table.getRow(i);
            List<XWPFTableCell> cells = row.getTableCells();
            for (int j = 0; j < cells.size(); j++) {
                cells.get(j).setText(tableList.get(i)[j]);
            }
        }

    }


    /**
     * 饼图
     *
     * @param document
     * @param title      图的标题
     * @param valueTitle 图种类名称
     * @param values     图种类的值
     */
    public void createPieChart(XWPFDocument document, String title, String[] valueTitle, Double[] values) throws IOException, InvalidFormatException {

        XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
        // 标题
        chart.setTitleText(title);
        // 标题是否覆盖图表
        chart.setTitleOverlay(false);

        // 图例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP_RIGHT);

        XDDFCategoryDataSource categorys = XDDFDataSourcesFactory.fromArray(valueTitle);

        XDDFNumericalDataSource<Double> numerical = XDDFDataSourcesFactory.fromArray(values);

        XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);
        // 设置为可变颜色
        data.setVaryColors(true);
        // 图表加载数据
        data.addSeries(categorys, numerical);
        // 绘制
        chart.plot(data);

        CTDLbls dLbls = chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).addNewDLbls();
        dLbls.addNewShowVal().setVal(false);//不显示值
        dLbls.addNewShowLegendKey().setVal(false);
        dLbls.addNewShowCatName().setVal(true);//类别名称
        dLbls.addNewShowSerName().setVal(false);//不显示系列名称
        dLbls.addNewShowPercent().setVal(true);//显示百分比
        dLbls.addNewShowLeaderLines().setVal(true); //显示引导线

    }

    /**
     * 柱状图
     *
     * @param document
     * @param title      标题
     * @param xAxisTitle X轴标题
     * @param yAxisTitle Y轴标题
     * @param categorys  种类
     * @param values     值
     * @throws IOException
     * @throws InvalidFormatException
     */
    public void createBarChart(XWPFDocument document, String title, String xAxisTitle, String yAxisTitle, String[] categorys, Map<String, Number[]> values) throws IOException, InvalidFormatException {

        XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
        // 标题
        chart.setTitleText(title);
        // 标题覆盖
        chart.setTitleOverlay(false);
        // 图例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP);
        legend.setOverlay(true);

        //X轴属性
        XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        xAxis.setTitle(xAxisTitle);

        // Y轴属性
        XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT);
        yAxis.setTitle(yAxisTitle);
        yAxis.setCrosses(AxisCrosses.AUTO_ZERO);
        yAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

        XDDFChartData data = chart.createData(ChartTypes.BAR, xAxis, yAxis);
        data.setVaryColors(true);
        ((XDDFBarChartData) data).setBarDirection(BarDirection.COL); // 设置方向为竖状

        XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromArray(categorys);
        values.forEach((k, v) -> {
            XDDFChartData.Series series = data.addSeries(categoriesData, XDDFDataSourcesFactory.fromArray(v));
            series.setTitle(k, null);
        });
        chart.plot(data);


    }


    /**
     * 柱状图
     *
     * @param document
     * @param title      标题
     * @param xAxisTitle X轴标题
     * @param yAxisTitle Y轴标题
     * @param categorys  种类
     * @param values     值
     * @throws IOException
     * @throws InvalidFormatException
     */
    public void createLineChart(XWPFDocument document, String title, String xAxisTitle, String yAxisTitle, String[] categorys, Map<String, Number[]> values) throws IOException, InvalidFormatException {
        XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);

        // 标题
        chart.setTitleText(title);
        // 标题覆盖
        chart.setTitleOverlay(false);
        // 图例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP);
        legend.setOverlay(true);

        //X轴属性
        XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        xAxis.setTitle(xAxisTitle);

        //Y轴属性
        XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT);
        yAxis.setTitle(yAxisTitle);

        // 折线图,
        XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, xAxis, yAxis);

        XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(categorys);
        // 加载数据
        values.forEach((k, v) -> {
            XDDFLineChartData.Series series = (XDDFLineChartData.Series) data.addSeries(countries, XDDFDataSourcesFactory.fromArray(v));
            series.setTitle(k, null); // 折线图例标题
            series.setMarkerStyle(MarkerStyle.CIRCLE); // 设置标记样式
        });
        // 绘制
        chart.plot(data);
    }

    /**
     * 柱状图
     *
     * @param document
     * @param title      标题
     * @param xAxisTitle X轴标题
     * @param yAxisTitle Y轴标题
     * @param categorys  种类
     * @param values     值
     * @throws IOException
     * @throws InvalidFormatException
     */
    public void createBarLineChart(XWPFDocument document, String title, String xAxisTitle, String yAxisTitle, String[] categorys, Map<String, Number[]> values) throws IOException, InvalidFormatException {
        XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);

        // 标题
        chart.setTitleText(title);
        // 标题覆盖
        chart.setTitleOverlay(false);
        // 图例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP);
        legend.setOverlay(true);

        //X轴属性
        XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        xAxis.setTitle(xAxisTitle);

        //Y轴属性
        XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT);
        yAxis.setTitle(yAxisTitle);
        yAxis.setCrosses(AxisCrosses.AUTO_ZERO);
        yAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

        // 折线图,
        XDDFLineChartData lineData = (XDDFLineChartData) chart.createData(ChartTypes.LINE, xAxis, yAxis);
        // 柱状图
        XDDFChartData barData = chart.createData(ChartTypes.BAR, xAxis, yAxis);
        barData.setVaryColors(true);
        ((XDDFBarChartData) barData).setBarDirection(BarDirection.COL); // 设置方向为竖状

        XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(categorys);
        // 加载数据
        values.forEach((k, v) -> {
            XDDFChartData.Series barSeries = barData.addSeries(countries, XDDFDataSourcesFactory.fromArray(v));
            barSeries.setTitle(k, null);
            XDDFLineChartData.Series lineSeries = (XDDFLineChartData.Series) lineData.addSeries(countries, XDDFDataSourcesFactory.fromArray(v));
            lineSeries.setTitle(k, null); // 折线图例标题
            lineSeries.setMarkerStyle(MarkerStyle.CIRCLE); // 设置标记样式
        });
        // 绘制
        chart.plot(lineData);
        chart.plot(barData);
    }

    /**
     * 正则匹配字符串
     *
     * @param str
     * @return
     */
    private Matcher matcher(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }
}

调用方法,根据需求自定义写入内容到Word

import com.poi.util.WordUtils;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** 
 * @author fax
 * @date 2023-08-23 11:08
 */
public class TestWord {
    public static void main(String[] args) {

        String content = "今天是个好日子";

        Map<String, Object> params = new HashMap<>();
        params.put("title", "真不错");
        params.put("content", content);
        params.put("header1", "大家都开心");
        params.put("header2", "好的");
        params.put("header3", "How are you?");
        params.put("header4", "fine");
        params.put("header5", "thank you!");

        List<String[]> table1 = new ArrayList<>();
        table1.add(new String[]{"1", "11", "22", "33", "44"});
        table1.add(new String[]{"2", "55", "66", "77", "88"});
        table1.add(new String[]{"2", "99", "1010", "1111", "1212"});

        List<String[]> table2 = new ArrayList<>();
        table2.add(new String[]{"1", "1313", "1414", "1515"});
        table2.add(new String[]{"2", "1616", "1717", "1818"});
        table2.add(new String[]{"3", "1919", "2020", "2121"});
        //饼图数据
        String[] title = new String[]{"1", "2", "3", "4", "5"};
        Double[] value = new Double[]{70.34, 40.5, 54.9, 334.8, 546.2};
        // 柱状图、折线图 数据

        String[] quarter = new String[]{"第一年", "第二年", "第三年", "第四年"};
        Map<String, Number[]> map = new HashMap<>();
        map.put("姜文", new Integer[]{6688, 4399, 5327, 6379});
        map.put("周润发", new Integer[]{6799, 7499, 6429, 7379});
        map.put("葛优", new Integer[]{5899, 6599, 7665, 8573});
        System.out.println(System.getProperty("user.dir"));
        String inPath = System.getProperty("user.dir") + "\\poi_demo\\src\\main\\resources\\template\\Template.docx";
        String outPath = "D:\\word文件.docx";
        try (InputStream is = new FileInputStream(inPath);
             OutputStream os = new FileOutputStream(outPath);
             XWPFDocument document = new XWPFDocument(OPCPackage.open(is))) {
            WordUtils wordUtils = new WordUtils();
            // 替换段落中的参数
            wordUtils.replaceInPara(document, params);
            // 替换表格中的参数
            wordUtils.replaceInTable(document, new int[]{0}, params);
            // 给表格追加记录
            wordUtils.insertTableRow(document.getTableArray(0), table1);
            // 创建表格
            wordUtils.createTitle(document.createParagraph(), "二、表格二");

            wordUtils.createTable(document, table2);
            // 创建饼图
            wordUtils.createTitle(document.createParagraph(), "三、饼图");
            wordUtils.createPieChart(document, "豆瓣评分", title, value);

            wordUtils.createTitle(document.createParagraph(), "四、柱形图");
            // 创建柱状图
            wordUtils.createBarChart(document, "标题", null, null, quarter, map);
            wordUtils.createTitle(document.createParagraph(), "五、条形图");
            // 创建柱状图
            wordUtils.createLineChart(document, "标题", "季度", "数值", quarter, map);
            wordUtils.createTitle(document.createParagraph(), "六、混合图");
            // 创建柱状图
            wordUtils.createBarLineChart(document, "标题", null, null, quarter, map);
            document.write(os);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,您可以使用以下步骤实现这个功能: 1. 在使用 Echarts 绘制图表时,将图表的数据保存在一个 state 中。 2. 创建一个按钮组件,使用 React 的 useState 钩子来创建一个状态变量,用于控制按钮点击事件。 3. 在按钮的点击事件中,使用 FileSaver.js 库将图表数据导出到 Word 文档中。 4. 将导出按钮组件和 Echarts 组件一起渲染,以便用户可以点击按钮导出数据。 下面是一个简单的代码示例: ```jsx import React, { useState } from 'react'; import ReactEcharts from 'echarts-for-react'; import * as FileSaver from 'file-saver'; const MyEcharts = () => { const [chartData, setChartData] = useState(null); const [exporting, setExporting] = useState(false); const handleExportClick = () => { setExporting(true); const chartDataStr = JSON.stringify(chartData); const blob = new Blob([chartDataStr], { type: 'application/json' }); FileSaver.saveAs(blob, 'chart-data.json'); setExporting(false); }; const options = { // Echarts 配置项 }; return ( <> <ReactEcharts option={options} onChartReady={e => setChartData(e.getOption())} /> <button disabled={exporting} onClick={handleExportClick}> {exporting ? 'Exporting...' : 'Export to Word'} </button> </> ); }; ``` 在这个示例中,我们使用了 ReactEcharts 组件来绘制图表,并使用 onChartReady 回调将图表数据保存到 state 中。然后,我们创建了一个按钮组件,并在点击事件中使用 FileSaver.js 库将图表数据导出到 Word 文档中。最后,我们将导出按钮组件和 Echarts 组件一起渲染,以便用户可以点击按钮导出数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值