我用poi生成图表,想把刻度标记间隔调大一点
设置bottomAxis.setMajorUnit(10),但是不生效,点开源码看
点开源码看,源码直接就nothing
我需要通过什么才可以调整刻度标记间隔呢?下面是完整的代码
package echarts.echarts;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
import org.apache.poi.xddf.usermodel.chart.AxisTickLabelPosition;
import org.apache.poi.xddf.usermodel.chart.AxisTickMark;
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
import org.apache.poi.xddf.usermodel.chart.MarkerStyle;
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
import org.apache.poi.xddf.usermodel.chart.XDDFLineChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import cn.hutool.core.date.DateUtil;
public class App2 {
public static void main(String[] args) throws IOException {
XSSFWorkbook wb = new XSSFWorkbook();
FileOutputStream fileOut = null;
try {
// 轨迹点Sheet
XSSFSheet sheet = wb.createSheet("轨迹点");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("时间");
cell = row.createCell(1);
cell.setCellValue("温度");
Date date = DateUtil.parse("2023-05-10 00:00:00");
Calendar cal = Calendar.getInstance();
cal.setTime(date);
double wd = -20.1;
for (int i = 1; i <= 5000; i++) {
row = sheet.createRow(i);
cell = row.createCell(0);
cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) + 30);
cell.setCellValue( DateUtil.format(cal.getTime(), "yyyy-mm-dd HH:mm:ss"));
cell = row.createCell(1);
// cell.setCellValue(RD());
// cell.setCellValue(wd);
cell.setCellValue(Math.abs(wd));
wd = wd + (0.0059 * Math.abs(RD()));
}
// 温度图表Sheet
XSSFSheet sheet2 = wb.createSheet("温度图表");
// 创建一个画布
XSSFDrawing drawing = sheet2.createDrawingPatriarch();
// 前四个默认0,[1,1]:从1列1行开始;[17,36]:到18列32行结束
// 默认宽度(14-8)*12
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 18, 32);
// 创建一个chart对象
XSSFChart chart = drawing.createChart(anchor);
// 标题
chart.setTitleText("温度图表");
// 标题覆盖
chart.setTitleOverlay(false);
// 图例位置
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.RIGHT);
// 分类轴标(X轴),标题位置
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setTickLabelPosition(AxisTickLabelPosition.LOW);
bottomAxis.setMajorUnit(10);
bottomAxis.setMajorTickMark(AxisTickMark.OUT);
// 值(Y轴)轴,标题位置
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
// leftAxis.setTitle("温度");
// CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
// 分类轴标(X轴)数据,单元格范围位置[0, 0]到[0, 6]
XDDFDataSource<String> countries = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(1, 5001, 0, 0));
// 数据1,单元格范围位置[1, 0]到[1, 6]
XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 5001, 1, 1));
// // LINE:折线图,
XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
// 图表加载数据,折线1
XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(countries, area);
// 折线图例标题
// CellReference cf = new CellReference();
series1.setTitle("温度", null);
// 直线
series1.setSmooth(false);
// 设置标记大小
// series1.setMarkerSize((short) 0);
// 设置标记样式,星星
series1.setMarkerStyle(MarkerStyle.NONE);
// // 绘制
chart.plot(data);
// 打印图表的xml
System.out.println(chart.getCTChart());
// 将输出写入excel文件
String filename = "排行榜前七的国家.xlsx";
fileOut = new FileOutputStream(filename);
wb.write(fileOut);
} catch (Exception e) {
e.printStackTrace();
} finally {
wb.close();
if (fileOut != null) {
fileOut.close();
}
}
}
//随机数产生机器
static int min = -5;
static int max = 10;
static int RD() {
Random random = new Random();
int n = random.nextInt(10);
if (Math.abs(min) > Math.abs(max)) {// 这里去了最大的绝对值最为正负数的范围,需要负数部分直产生负数的话可以分开做
if (n == 1 || n == 3 || n == 5 || n == 7 || n == 9) {
// 如果是13579进入负数生产机器
String str = "-" + random.nextInt(Math.abs(min));// 加个负号
int a = Integer.parseInt(str);// 把字符串str封装成实数a
return a;
} else {
// 否则产生正数,也就是说02468产生正数
int a = random.nextInt(Math.abs(min));
return a;
}
} else {
if (n == 1 || n == 3 || n == 5 || n == 7 || n == 9) {
// 如果是13579进入负数生产机器
String str = "-" + random.nextInt(Math.abs(min));// 加个负号
int a = Integer.parseInt(str);// 把字符串str封装成实数a
return a;
} else {
// 否则产生正数,也就是说02468产生正数
int a = random.nextInt(Math.abs(min));
return a;
}
}
}
}
XDDFCategoryAxis 这个不支持设置刻度标记间隔,你可能得用XDDFValueAxis 这个类
要调整X轴刻度标记间隔,可以使用XDDFCategoryAxis类的setMajorUnit()方法。这个方法的参数是一个double类型的值,表示刻度标记之间的距离。例如,如果想让刻度标记之间的距离为10,则可以调用setMajorUnit(10)。
在您的代码中,可以在以下行添加调用setMajorUnit()方法的代码,以调整X轴刻度标记间隔:
Copy
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setTickLabelPosition(AxisTickLabelPosition.LOW);
bottomAxis.setMajorUnit(10); // 设置刻度标记间隔为10
bottomAxis.setMajorTickMark(AxisTickMark.OUT);
这样,X轴上的刻度标记将以10个时间单位为间隔显示。您可以根据需要调整这个值。
可以借鉴下
//字体样式 宋体 加粗 11
HSSFFont font = workbook.createFont();
font.setBold(true);
font.setFontHeightInPoints((short)11);
font.setFontName("宋体");
//创建表格样式 文字居中,四边边框
HSSFCellStyle style=workbook.createCellStyle();
style.setFont(font);
style.setWrapText(true);
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderBottom(BorderStyle.THIN); //下边框
style.setBorderLeft(BorderStyle.THIN);//左边框
style.setBorderTop(BorderStyle.THIN);//上边框
style.setBorderRight(BorderStyle.THIN);//右边框
//设置背景色的时候需要先设置填充样式,在设置颜色(个人理解)
//设置前景填充样式
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
//前景填充色
style.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
基于GPT4和Treabhar的编写:
bottomAxis.setMajorUnit(10)
这个方法并没有生效。这可能是因为POI库并不完全支持所有Excel的功能,特别是一些高级的图表功能。bottomAxis.setMajorUnit(10)
这个方法在POI的源代码中是空的,也就是说它实际上并没有做任何事情。引用ChatGPT部分内容作参考:
您好,根据您提供的代码,可以通过设置XDDFCategoryAxis的setMajorUnit方法来调整刻度标记间隔。在您的代码中,已经有以下代码:
// 分类轴标(X轴),标题位置
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setTickLabelPosition(AxisTickLabelPosition.LOW);
bottomAxis.setMajorUnit(10);
bottomAxis.setMajorTickMark(AxisTickMark.OUT);
其中,setMajorUnit方法可以设置刻度标记的间隔,这里设置为10。如果想要调整间隔,只需要修改这个值即可。另外,如果刻度标记过于密集,可以考虑使用setTickLabelSkip方法来跳过一些刻度标记的显示,例如:
bottomAxis.setTickLabelSkip(10);
这样可以每隔10个刻度标记显示一个
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
根据代码,你创建了一个XDDFCategoryAxis作为X轴,但是在设置标记间隔时,你使用的是setMajorUnit方法,这个方法是设置每个主刻度标记之间的类别宽度,而不是设置刻度标记之间的间隔。
要设置刻度标记间隔,可以使用setTickUnit方法,例如:bottomAxis.setTickUnit(10);就可以将刻度标记的间隔设置为10。
以下是更正后的代码:
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.chart.AxisPosition;
import org.apache.poi.xddf.usermodel.chart.AxisTickLabelPosition;
import org.apache.poi.xddf.usermodel.chart.AxisTickMark;
import org.apache.poi.xddf.usermodel.chart.ChartTypes;
import org.apache.poi.xddf.usermodel.chart.LegendPosition;
import org.apache.poi.xddf.usermodel.chart.MarkerStyle;
import org.apache.poi.xddf.usermodel.chart.XDDFCategoryAxis;
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
import org.apache.poi.xddf.usermodel.chart.XDDFLineChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import cn.hutool.core.date.DateUtil;
public class App2 {
public static void main(String[] args) throws IOException {
XSSFWorkbook wb = new XSSFWorkbook();
FileOutputStream fileOut = null;
try {
// 轨迹点Sheet
XSSFSheet sheet = wb.createSheet("轨迹点");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("时间");
cell = row.createCell(1);
cell.setCellValue("温度");
Date date = DateUtil.parse("2023-05-10 00:00:00");
Calendar cal = Calendar.getInstance();
cal.setTime(date);
double wd = -20.1;
for (int i = 1; i <= 5000; i++) {
row = sheet.createRow(i);
cell = row.createCell(0);
cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) + 30);
cell.setCellValue(DateUtil.format(cal.getTime(), "yyyy-mm-dd HH:mm:ss"));
cell = row.createCell(1);
cell.setCellValue(Math.abs(wd));
wd = wd + (0.0059 * Math.abs(RD()));
}
// 温度图表Sheet
XSSFSheet sheet2 = wb.createSheet("温度图表");
// 创建一个画布
XSSFDrawing drawing = sheet2.createDrawingPatriarch();
// 前四个默认0,[1,1]:从1列1行开始;[17,36]:到18列32行结束
// 默认宽度(14-8)*12
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 18, 32);
// 创建一个chart对象
XSSFChart chart = drawing.createChart(anchor);
// 标题
chart.setTitleText("温度图表");
// 标题覆盖
chart.setTitleOverlay(false);
// 图例位置
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.RIGHT);
// 分类轴标(X轴),标题位置
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setTickLabelPosition(AxisTickLabelPosition.LOW);
bottomAxis.setTickUnit(10);
bottomAxis.setMajorTickMark(AxisTickMark.OUT);
// 值(Y轴)轴,标题位置
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
// CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
// 分类轴标(X轴)数据,单元格范围位置[0, 0]到[0, 6]
XDDFDataSource<String> countries = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(1, 5001, 0, 0));
// 数据1,单元格范围位置[1, 0]到[1, 6]
XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 5001, 1, 1));
XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
// 图表加载数据,折线1
XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(countries, area);
// 折线图例标题
series1.setTitle("温度", null);
// 直线
series1.setSmooth(false);
// 设置标记样式,星星
series1.setMarkerStyle(MarkerStyle.NONE);
// 绘制
chart.plot(data);
// 打印图表的xml
System.out.println(chart.getCTChart());
// 将输出写入excel文件
String filename = "排行榜前七的国家.xlsx";
fileOut = new FileOutputStream(filename);
wb.write(fileOut);
} catch (Exception e) {
e.printStackTrace();
} finally {
wb.close();
if (fileOut != null) {
fileOut.close();
}
}
}
//随机数产生机器
static int min = -5;
static int max = 10;
static int RD() {
Random random = new Random();
int n = random.nextInt(10);
if (Math.abs(min) > Math.abs(max)) {
if (n == 1 || n == 3 || n == 5 || n == 7 || n == 9) {
String str = "-" + random.nextInt(Math.abs(min));
int a = Integer.parseInt(str);
return a;
} else {
int a = random.nextInt(Math.abs(min));
return a;
}
} else {
if (n == 1 || n == 3 || n == 5 || n == 7 || n == 9) {
String str = "-" + random.nextInt(Math.abs(min));
int a = Integer.parseInt(str);
return a;
} else {
int a = random.nextInt(Math.abs(min));
return a;
}
}
}
}
如果我的回答解决了您的问题,请采纳!
以下答案由GPT-4.5Plus大模型(语音)与博主A努力中.......共同编写:
根据你的代码和描述,出现setMajorUnit()不生效的原因可能有以下几个:
java
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
如果类型不匹配,setMajorUnit()方法将不生效。
majorUnit值设置过大。如果将刻度间隔设置为原有刻度数的很大倍数,POI可能忽略这一设置,以免刻度间隔过大影响显示效果。
bottomAxis的刻度已经固定。如果底轴刻度已经通过其他方式固定,则后续setMajorUnit()调用将不生效。
图表类型不支持刻度间隔调整。个别图表类型的底轴刻度间隔不可调整,setMajorUnit()设置将失效。
POI版本问题。不同POI版本的图表实现细节可能不同,导致setMajorUnit()在某版本下不生效。
解决方法: