当前位置: 首页 > wzjs >正文

定制做网站站长统计幸福宝下载

定制做网站,站长统计幸福宝下载,wordpress+pdo+mysql扩展,高端的网站优化公司📊 支持图表导出功能! 支持将 柱状图、折线图 图表以 Word 文档格式导出,并保留图例、坐标轴、颜色、数据标签等完整信息。 如需使用该功能,请私聊我,备注 “导出柱状图 / 折线图”。 生成的效果图如下:示例…

📊 支持图表导出功能!

支持将 柱状图折线图 图表以 Word 文档格式导出,并保留图例、坐标轴、颜色、数据标签等完整信息。

如需使用该功能,请私聊我,备注 “导出柱状图 / 折线图”

生成的效果图如下:

在这里插入图片描述

示例调用方式

package com.gemantic.qflow.word.utils;import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.XDDFColor;
import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFPieChartData;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFChart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDLbls;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer;import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;/*** 饼图渲染工具类:用于在Word文档中生成饼图。* 支持自定义颜色、图例位置、数据标签显示等参数。* 当单个数据点包含多个值时,自动取第一个值作为饼图数据。*/
public class PieChartRenderer {/*** 测试主方法,直接运行可生成示例Word文档并导出到本地。* @param args 命令行参数* @throws IOException 文件写入异常* @throws InvalidFormatException 图表格式异常*/public static void main(String[] args) throws IOException, InvalidFormatException {// 使用用户提供的JSON数据结构进行测试String jsonData = "{\n" +"    \"type\": \"chart_pie\",\n" +"    \"chartType\": \"pie\",\n" +"    \"title\": \"股价对比图表\",\n" +"    \"xAxisTitle\": \"日期\",\n" +"    \"yAxisTitle\": \"价格\",\n" +"    \"legend\": [],\n" +"    \"value\": [\n" +"        { \"name\": \"2022/11/12\", \"value\": [120.99,2000] },\n" +"        { \"name\": \"2022/11/13\", \"value\": [null] },\n" +"        { \"name\": \"2022/11/14\", \"value\": [150] },\n" +"        { \"name\": \"2022/11/15\", \"value\": [160] },\n" +"        { \"name\": \"2022/11/16\", \"value\": [180] }\n" +"    ],\n" +"    \"colors\": [\n" +"        \"#4E79A7\",\n" +"        \"#29A0CA\"\n" +"    ],\n" +"    \"showTitle\": true,\n" +"    \"showGrid\": true,\n" +"    \"showLegend\": true,\n" +"    \"showAxisLabel\": true,\n" +"    \"showDataLabel\": true,\n" +"    \"showAxis\": true,\n" +"    \"width\": 600,\n" +"    \"height\": 400\n" +"}";new PieChartRenderer().renderFromJson(new XWPFDocument(), jsonData);}/*** 基于JSON字符串渲染饼图到Word文档* @param doc 目标XWPFDocument文档对象* @param jsonData JSON字符串,包含饼图配置和数据* @throws IOException 文件写入异常* @throws InvalidFormatException 图表格式异常*/public void renderFromJson(XWPFDocument doc, String jsonData) throws IOException, InvalidFormatException {ObjectMapper mapper = new ObjectMapper();JsonNode rootNode = mapper.readTree(jsonData);// 解析基本配置String chartType = rootNode.get("chartType").asText(); // 应该是 "pie"String title = rootNode.get("title").asText();// 【图表标题】是否显示图表主标题。true:显示。false:不显示。boolean showTitle = rootNode.get("showTitle").asBoolean();// 【图例】是否显示图例。boolean showLegend = rootNode.get("showLegend").asBoolean();// 【数据标签】是否在图表上直接显示每个数据点的数值标签。true:显示。false:不显示。boolean showDataLabel = rootNode.get("showDataLabel").asBoolean();// 饼图的尺寸配置int width = rootNode.has("width") ? rootNode.get("width").asInt() : 600;int height = rootNode.has("height") ? rootNode.get("height").asInt() : 400;// 解析颜色配置List<String> colors = new ArrayList<>();JsonNode colorsNode = rootNode.get("colors");if (colorsNode != null) {for (JsonNode color : colorsNode) {colors.add(color.asText());}}// 解析饼图数据JsonNode valueNode = rootNode.get("value");List<String> categories = new ArrayList<>();List<Double> values = new ArrayList<>();// 解析每个数据点,如果有多个值则取第一个,过滤掉null或无效值for (JsonNode dataPoint : valueNode) {String name = dataPoint.get("name").asText();JsonNode valueArray = dataPoint.get("value");Double validValue = null;if (valueArray.isArray() && valueArray.size() > 0) {// 遍历值数组,找到第一个有效的非null数值for (int i = 0; i < valueArray.size(); i++) {JsonNode valueNode2 = valueArray.get(i);if (!valueNode2.isNull() && valueNode2.isNumber()) {double val = valueNode2.asDouble();// 只接受大于0的有效值(饼图不能有负值或0值)if (val > 0) {validValue = val;break;}}}}// 只添加有有效值的数据点到饼图中if (validValue != null) {categories.add(name);values.add(validValue);System.out.println("✅ 添加饼图数据点:" + name + " = " + validValue);} else {System.out.println("⚠️ 跳过无效数据点:" + name + "(值为null、0或负数)");}}// 转换为数组String[] categoryArray = categories.toArray(new String[0]);Double[] valueArray = values.toArray(new Double[0]);// 创建饼图createPieChart(doc, title, categoryArray, valueArray, colors,showDataLabel, showTitle, showLegend, width, height);// 保存文件String outputPath = "/Users/wtm/Desktop/output/pie_chart_" + System.currentTimeMillis() + ".docx";try (FileOutputStream out = new FileOutputStream(outputPath)) {doc.write(out);}System.out.println("✅ 饼图导出完成,路径:" + outputPath);}/*** 创建饼图的核心方法* @param doc 目标XWPFDocument文档对象* @param chartTitle 图表标题* @param categories 饼图分类标签数组* @param values 饼图数值数组* @param colors 颜色列表* @param showDataLabels 是否显示数据标签* @param showTitle 是否显示图表标题* @param showLegend 是否显示图例* @param width 图表宽度(像素)* @param height 图表高度(像素)* @throws IOException 文件写入异常* @throws InvalidFormatException 图表格式异常*/private void createPieChart(XWPFDocument doc,String chartTitle,String[] categories,Double[] values,List<String> colors,boolean showDataLabels,boolean showTitle,boolean showLegend,int width,int height) throws IOException, InvalidFormatException {// 创建段落标题XWPFParagraph p = doc.createParagraph();p.setAlignment(ParagraphAlignment.CENTER);XWPFRun r = p.createRun();r.setText(chartTitle);r.setBold(true);r.setFontSize(16);// 创建图表对象 - 使用JSON提供的尺寸,转换为EMU单位int widthEMU = (int) (width * Units.EMU_PER_PIXEL);int heightEMU = (int) (height * Units.EMU_PER_PIXEL);XWPFChart chart = doc.createChart(widthEMU, heightEMU);// 首先填充嵌入的Excel数据,确保数据源正确建立populateEmbeddedExcelDataForPie(chart, categories, values);// 设置图表标题显示/隐藏if (showTitle) {chart.setTitleText(chartTitle);chart.setTitleOverlay(false);} else {// 隐藏图表标题chart.setTitleText("");chart.setTitleOverlay(true);}// 设置图例显示/隐藏if (showLegend) {XDDFChartLegend legend = chart.getOrAddLegend();legend.setPosition(LegendPosition.BOTTOM); // 【修改】图例位置设置为底部} else {// 隐藏图例if (chart.getCTChart().isSetLegend()) {chart.getCTChart().unsetLegend();}}// 使用Excel工作表数据作为数据源XDDFCategoryDataSource categoryDataSource = createCategoryDataSourceFromExcelForPie(chart, categories.length);XDDFNumericalDataSource<Double> valuesDataSource = createNumericalDataSourceFromExcelForPie(chart, categories.length);// 创建饼图数据XDDFPieChartData data = (XDDFPieChartData) chart.createData(ChartTypes.PIE, null, null);// 添加饼图系列XDDFPieChartData.Series series = (XDDFPieChartData.Series) data.addSeries(categoryDataSource, valuesDataSource);series.setTitle("饼图数据", null);// 设置数据标签setPieDataLabels(series, showDataLabels, values);// 设置饼图扇形颜色setPieSeriesColors(series, colors, categories.length);// 绘制图表chart.plot(data);System.out.println("✅ 饼图创建完成,包含 " + categories.length + " 个扇形");}/*** 填充嵌入的Excel数据,专门为饼图设计* @param chart XWPFChart对象* @param categories 饼图分类标签* @param values 饼图数值*/private void populateEmbeddedExcelDataForPie(XWPFChart chart, String[] categories, Double[] values) {try {// 获取嵌入的Excel工作簿if (chart.getWorkbook() != null) {org.apache.poi.ss.usermodel.Workbook workbook = chart.getWorkbook();// 获取第一个工作表,如果不存在则创建org.apache.poi.ss.usermodel.Sheet sheet = workbook.getNumberOfSheets() > 0 ?workbook.getSheetAt(0) : workbook.createSheet("PieChartData");// 设置工作表名称if (workbook.getNumberOfSheets() > 0) {workbook.setSheetName(0, "PieChartData");}// 清空现有数据for (int i = sheet.getLastRowNum(); i >= 0; i--) {org.apache.poi.ss.usermodel.Row row = sheet.getRow(i);if (row != null) {sheet.removeRow(row);}}// 创建表头行org.apache.poi.ss.usermodel.Row headerRow = sheet.createRow(0);headerRow.createCell(0).setCellValue("分类"); // 第一列为分类标题headerRow.createCell(1).setCellValue("数值"); // 第二列为数值标题// 填充数据行for (int i = 0; i < categories.length && i < values.length; i++) {org.apache.poi.ss.usermodel.Row dataRow = sheet.createRow(i + 1);dataRow.createCell(0).setCellValue(categories[i]);dataRow.createCell(1).setCellValue(values[i] != null ? values[i] : 0.0);}// 自动调整列宽sheet.autoSizeColumn(0);sheet.autoSizeColumn(1);// 设置数据区域名称,便于图表引用org.apache.poi.ss.usermodel.Name dataRange = workbook.createName();dataRange.setNameName("PieChartDataRange");String rangeFormula = "PieChartData!$A$1:$B$" + (categories.length + 1);dataRange.setRefersToFormula(rangeFormula);System.out.println("✅ 已填充饼图嵌入Excel数据,包含 " + (categories.length + 1) + " 行 2 列");System.out.println("✅ 饼图数据范围设置为:" + rangeFormula);}} catch (Exception e) {System.err.println("警告:填充饼图嵌入Excel数据时出错:" + e.getMessage());e.printStackTrace();}}/*** 从Excel工作表创建分类数据源(专门为饼图设计)* @param chart XWPFChart对象* @param categoryCount 分类数量* @return 分类数据源*/private XDDFCategoryDataSource createCategoryDataSourceFromExcelForPie(XWPFChart chart, int categoryCount) {try {// 创建引用Excel第一列的数据源(A2:A[n],跳过标题行)return XDDFDataSourcesFactory.fromStringCellRange(chart.getWorkbook().getSheetAt(0),new org.apache.poi.ss.util.CellRangeAddress(1, categoryCount, 0, 0));} catch (Exception e) {System.err.println("警告:无法创建饼图Excel分类数据源,使用默认数据源:" + e.getMessage());// 如果失败,返回默认的字符串数组数据源String[] defaultCategories = new String[categoryCount];for (int i = 0; i < categoryCount; i++) {defaultCategories[i] = "分类" + (i + 1);}return XDDFDataSourcesFactory.fromArray(defaultCategories);}}/*** 从Excel工作表创建数值数据源(专门为饼图设计)* @param chart XWPFChart对象* @param dataCount 数据行数* @return 数值数据源*/private XDDFNumericalDataSource<Double> createNumericalDataSourceFromExcelForPie(XWPFChart chart, int dataCount) {try {// 创建引用Excel第二列的数据源(B2:B[n],跳过标题行)return XDDFDataSourcesFactory.fromNumericCellRange(chart.getWorkbook().getSheetAt(0),new org.apache.poi.ss.util.CellRangeAddress(1, dataCount, 1, 1));} catch (Exception e) {System.err.println("警告:无法创建饼图Excel数值数据源,使用默认数据源:" + e.getMessage());// 如果失败,返回默认的数值数组数据源Double[] defaultData = new Double[dataCount];for (int i = 0; i < dataCount; i++) {defaultData[i] = (double) (i + 1) * 10; // 简单的递增数据}return XDDFDataSourcesFactory.fromArray(defaultData);}}/*** 设置饼图数据标签* @param series 饼图系列* @param showDataLabels 是否显示数据标签* @param values 数值数组(用于确定哪些点需要标签)*/private void setPieDataLabels(XDDFPieChartData.Series series, boolean showDataLabels, Double[] values) {if (!showDataLabels) {// 关闭所有标签CTPieSer ctSer = series.getCTPieSer();if (ctSer.isSetDLbls()) {ctSer.unsetDLbls();}return;}try {// 为饼图显示数据标签CTPieSer ctSer = series.getCTPieSer();CTDLbls dLbls = ctSer.isSetDLbls() ? ctSer.getDLbls() : ctSer.addNewDLbls();// 清空原有标签dLbls.setDLblArray(null);// 全局标签设置:显示数值dLbls.addNewShowVal().setVal(true);dLbls.addNewShowLegendKey().setVal(false);dLbls.addNewShowCatName().setVal(false);dLbls.addNewShowSerName().setVal(false);dLbls.addNewShowPercent().setVal(false);dLbls.addNewShowLeaderLines().setVal(true); // 饼图特有:显示引导线// 为每个有值的数据点设置标签for (int i = 0; i < values.length; i++) {if (values[i] != null && values[i] > 0) {org.openxmlformats.schemas.drawingml.x2006.chart.CTDLbl lbl = dLbls.addNewDLbl();lbl.addNewIdx().setVal(i);lbl.addNewShowVal().setVal(true);lbl.addNewShowLegendKey().setVal(false);lbl.addNewShowCatName().setVal(false);lbl.addNewShowSerName().setVal(false);lbl.addNewShowPercent().setVal(false);}}System.out.println("✅ 已设置饼图数据标签,显示 " + values.length + " 个数据点的标签");} catch (Exception e) {System.err.println("警告:设置饼图数据标签时出错:" + e.getMessage());}}/*** 设置饼图扇形颜色* @param series 饼图系列* @param colors 颜色列表* @param pointCount 数据点数量*/private void setPieSeriesColors(XDDFPieChartData.Series series, List<String> colors, int pointCount) {if (colors == null || colors.isEmpty()) {System.out.println("⚠️ 未提供颜色配置,将使用默认颜色");return;}try {// 为每个饼图扇形设置颜色for (int i = 0; i < pointCount; i++) {// 使用模运算实现颜色循环:当颜色数量少于数据点时循环使用String colorHex = colors.get(i % colors.size());setPieSliceColor(series, i, colorHex);}System.out.println("✅ 已设置饼图扇形颜色,使用 " + colors.size() + " 种颜色为 " + pointCount + " 个扇形着色");} catch (Exception e) {System.err.println("警告:设置饼图颜色时出错:" + e.getMessage());}}/*** 设置单个饼图扇形的颜色* @param series 饼图系列* @param pointIndex 数据点索引* @param colorHex 十六进制颜色值(如 #4E79A7)*/private void setPieSliceColor(XDDFPieChartData.Series series, int pointIndex, String colorHex) {try {// 移除颜色字符串前的#号String hex = colorHex.startsWith("#") ? colorHex.substring(1) : colorHex;// 将十六进制颜色转换为RGBint r = Integer.parseInt(hex.substring(0, 2), 16);int g = Integer.parseInt(hex.substring(2, 4), 16);int b = Integer.parseInt(hex.substring(4, 6), 16);// 创建颜色对象XDDFColor xddfColor = XDDFColor.from(new byte[]{(byte)r, (byte)g, (byte)b});XDDFSolidFillProperties fillProperties = new XDDFSolidFillProperties(xddfColor);// 设置饼图扇形颜色XDDFShapeProperties shapeProperties = new XDDFShapeProperties();shapeProperties.setFillProperties(fillProperties);// 通过底层CT对象设置特定数据点的颜色CTPieSer ctSer = series.getCTPieSer();if (ctSer.getDPtArray().length <= pointIndex) {// 如果数据点不存在,创建新的数据点while (ctSer.getDPtArray().length <= pointIndex) {org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt dPt = ctSer.addNewDPt();dPt.addNewIdx().setVal(ctSer.getDPtArray().length - 1);}}org.openxmlformats.schemas.drawingml.x2006.chart.CTDPt dPt = ctSer.getDPtArray(pointIndex);if (dPt == null) {dPt = ctSer.addNewDPt();dPt.addNewIdx().setVal(pointIndex);}// 设置数据点的填充属性if (!dPt.isSetSpPr()) {dPt.addNewSpPr();}if (!dPt.getSpPr().isSetSolidFill()) {dPt.getSpPr().addNewSolidFill();}if (!dPt.getSpPr().getSolidFill().isSetSrgbClr()) {dPt.getSpPr().getSolidFill().addNewSrgbClr();}// 设置RGB颜色值dPt.getSpPr().getSolidFill().getSrgbClr().setVal(new byte[]{(byte)r, (byte)g, (byte)b});} catch (Exception e) {// 如果颜色格式错误,记录错误但不中断流程System.err.println("警告:无法解析颜色 " + colorHex + " 用于数据点 " + pointIndex + ",将使用默认颜色。错误:" + e.getMessage());}}
}

文章转载自:

http://Kf8oyTfD.mwbqk.cn
http://F6oN8O6H.mwbqk.cn
http://g0oJwj23.mwbqk.cn
http://NZnU3EL5.mwbqk.cn
http://5Ac7Og8g.mwbqk.cn
http://LhOg4YWb.mwbqk.cn
http://1xPhTYdq.mwbqk.cn
http://SfGhzmhg.mwbqk.cn
http://7QGKfB1w.mwbqk.cn
http://vxmWfQGP.mwbqk.cn
http://dxKlFwRR.mwbqk.cn
http://bzuIaR8r.mwbqk.cn
http://ysTUD7X8.mwbqk.cn
http://Tc0QNl6M.mwbqk.cn
http://mYcyaEWd.mwbqk.cn
http://IXcpra2M.mwbqk.cn
http://MmiXW4FP.mwbqk.cn
http://iHFfCdYM.mwbqk.cn
http://ql26Nh7N.mwbqk.cn
http://ccBZCk8t.mwbqk.cn
http://ZeuW9qzB.mwbqk.cn
http://CJ2HuiQG.mwbqk.cn
http://hO5Iq14v.mwbqk.cn
http://wvEs3ij1.mwbqk.cn
http://grRpIbYL.mwbqk.cn
http://UjF5wmn9.mwbqk.cn
http://q6no1IBU.mwbqk.cn
http://4PgY2Zg4.mwbqk.cn
http://S0DWcEmL.mwbqk.cn
http://exH1gZvR.mwbqk.cn
http://www.dtcms.com/wzjs/627647.html

相关文章:

  • 微设计公司网站网站推广的方法是什么
  • 主机屋网站空间的IPwordpress国主题
  • 长沙哪家公司做网站如何在小红书上做推广
  • 微信菜单怎么做微网站wordpress啥意思
  • 厦门启明星网站建设关于网站备案及管理的授权书
  • 怎么建医疗网站网页制作网页设计
  • 怎么把网站做10万ip企业建网站公司多少钱
  • 域名对行业网站的作用wordpress作者英文版
  • 上百度推广的网站要多少钱六安新闻 最新消息
  • 网站关键字优化教程全国文明城市创建标语
  • 本地wordpress建站建行购物网站
  • 网站建设方案规划书iis 与 wordpress
  • 网站重构案例网页设计文字教程
  • 国办网站建设规范看剧资源网站怎么做的
  • 商城网站模板html网络公司资质包括哪些
  • 搭建好网站如何使用宁波seo公司排名
  • 网站地图在线生成器四川建设学习网官网
  • 网站安全建设总结报告环保工程网站建设价格
  • 门户网站建设管理工作方案廊坊建站
  • 发软文的网站吉林省建设工程造价信息网
  • 网站301重定向代码小程序app系统开发
  • 新乡微信网站建设文字类wordpress主题
  • 织梦cms怎样做网站logo库官网
  • 惠州网站建设企业百度seo排名优化技巧分享
  • 弱电网站源码wordpress读取相册
  • 网站建设关键词排名优化好看的博客页面
  • 网站设计公司上海帝国cms网站搬家
  • 公司网站建设需推广学校网站建设培训方案
  • 上海 响应式网站公司泊头市有做网站的吗
  • 电影采集网站流量免费企业邮箱号有哪些