itextpdf 表格跨行跨列与可视化图表

article/2025/9/13 20:38:37

文章目录

  • itextpdf 表格跨行跨列与可视化图表
    • 效果图
      • 普通表格一(表头背景色)
      • 普通表格二 (隔列变色)
      • 表格跨行跨列
      • 可视化图表
    • 使用示例
      • 普通表格一(表头背景色)
      • 普通表格二 (隔列变色)
      • 表格跨行跨列
      • 可视化图表
    • 工具类源码
      • 依赖包
      • PdfUtil
      • GetData
      • RowData
      • TableDataUtil
      • ChartUtil

itextpdf 表格跨行跨列与可视化图表

效果图

普通表格一(表头背景色)

在这里插入图片描述

普通表格二 (隔列变色)

在这里插入图片描述

表格跨行跨列

在这里插入图片描述

可视化图表

饼图
在这里插入图片描述
柱状图
在这里插入图片描述
折线图
在这里插入图片描述

使用示例

普通表格一(表头背景色)

PdfUtil.addLevel2Title(doc, "对外投资信息");
PdfUtil.Table(7, textFont, new TableDataUtil().add(RowData.add("序号", "名称", "法定代表人", "注册资金", "注册号", "成立日期", "地址")).addList(GetData.get(desensitization, result, Compoent.INVESTMENTLIST, "NO", "InvestName", "Legal", "RegCapital", "EntRegNo", "EstDate", "RegAddress")).toList(), doc);

普通表格二 (隔列变色)

PdfUtil.addLevel2Title(doc, "社保基本信息");
PdfUtil.TableBuleColspan(4, textFont, new TableDataUtil().add(RowData.add("社保单位编号", GetData.get(result, Compoent.INHFSOCIALSECURITY, "SocialSecurityNo", desensitization), "投保起始年", GetData.get(result, Compoent.INHFSOCIALSECURITY, "InsuredYear"))).add(RowData.add("投保起始月", GetData.get(result, Compoent.INHFSOCIALSECURITY, "InsuredMonth"), "当前状态", GetData.get(result, Compoent.INHFSOCIALSECURITY, "CurrentState"))).add(RowData.add("参保总人数", GetData.get(result, Compoent.INHFSOCIALSECURITY, "TotalCNT"), "养老参保人数", GetData.get(result, Compoent.INHFSOCIALSECURITY, "EICNT"))).add(RowData.add("医疗参保人数", GetData.get(result, Compoent.INHFSOCIALSECURITY, "MICNT"), "工伤参保人数", GetData.get(result, Compoent.INHFSOCIALSECURITY, "IICNT"))).add(RowData.add("失业参保人数", GetData.get(result, Compoent.INHFSOCIALSECURITY, "UICNT"))).toList(), doc, new int[]{5}, new int[]{2}, new int[]{3});

表格跨行跨列

PdfUtil.TableBlueColRowSpan(4, textFont, new TableDataUtil().add(RowData.add("科目", "报表年份")).add(balanceSheetKeys).addList(RowData.add(balanceSheetDataGroup, (data) -> {List<List<String>> res = new ArrayList<>();data.forEach((k, v) -> {List<String> row = new ArrayList<>();row.add(k);Map<String, String> kv = v.stream().collect(Collectors.toMap(key -> String.valueOf(key.get("PeriodYear")), value -> String.valueOf(value.get("ClosingBalanceAsset"))));balanceSheetKeysGroup.keySet().forEach(i -> {row.add(Optional.ofNullable(kv.get(i)).orElse(""));});if (row.size() < 4) {for (int i = row.size() - 1; i < 3; i++) {row.add("");}}res.add(row);});return res;})).toList(), doc, new int[][]{{1}, {1}}, new int[][]{{2}, {1}}, new int[][]{{3}, {2}});

可视化图表

饼图

PdfPTable table = new PdfPTable(2);
table.setTotalWidth(530);
table.setLockedWidth(true);PdfPCell leftImage = new PdfPCell();bos = new ByteArrayOutputStream();
ChartUtils.writeChartAsJPEG(bos, ChartUtil.pieChart(String.join("", balanceSheetChartDataGroup.keySet()) + "资产结构", balanceSheetPieData), 400, 400);
image = Image.getInstance(bos.toByteArray());
image.scalePercent(60);
leftImage.addElement(image);
leftImage.disableBorderSide(-1);
table.addCell(leftImage);

柱状图

imageBaos = new ByteArrayOutputStream();
ChartUtils.writeChartAsJPEG(imageBaos, ChartUtil.barChart("", "", "", balanceSheetBarChartDataset, "{2}%"), 850, 330);
chartImage = Image.getInstance(imageBaos.toByteArray());
chartImage.scalePercent(60);
doc.add(chartImage);

折线图

ChartUtils.writeChartAsJPEG(imageBaos, ChartUtil.lineChart("用水量(立方)", "", "", waterLineDataset, CategoryLabelPositions.UP_90), 850, 430);
chartImage = Image.getInstance(imageBaos.toByteArray());
chartImage.scalePercent(60);
doc.add(chartImage);

工具类源码

依赖包

  • itextpdf 5.5.6
  • jfreechart 1.5.3

大家根据实际使用场景删除代码

PdfUtil

static class PdfUtil {public static void addLevel1Title(Document doc, String title) throws DocumentException {Paragraph p1 = new Paragraph(title, secondTitleFont);p1.setAlignment(Element.ALIGN_CENTER);doc.add(p1);}public static void addLevel2Title(Document doc, String title) throws DocumentException {Paragraph p1 = new Paragraph(title, threeTitleFont);p1.setAlignment(Element.ALIGN_LEFT);p1.setSpacingAfter(8);doc.add(p1);}public static void addOtherContent(Document doc, String content, int alignment, Font fontSize, float spacingAfter) throws DocumentException {Paragraph p1 = new Paragraph(content, fontSize);p1.setAlignment(alignment);p1.setSpacingAfter(spacingAfter);doc.add(p1);}public static void addLevel2Title(Document doc, String title, boolean newPage) throws DocumentException {doc.newPage();Paragraph p1 = new Paragraph(title, threeTitleFont);p1.setAlignment(Element.ALIGN_LEFT);p1.setSpacingAfter(8);doc.add(p1);}/*** 生成一个表格** @param total    总列数* @param textFont 字体* @param data     表格数据     X行    Y列* @param doc      PDF文档对象* @throws DocumentException* @author hou_fx*/public static void Table(int total, Font textFont, List<List<String>> data, Document doc) throws DocumentException {// 创建一个有N列的表格PdfPTable table = new PdfPTable(total);table.setPaddingTop(20);table.setSpacingAfter(20);table.setTotalWidth(530); //设置列宽table.setLockedWidth(true); //锁定列宽PdfPCell cell;for (int i = 0; i < data.size(); i++) {  //遍历数据行   每个数据行都是一个listIterator<String> it = data.get(i).iterator();while (it.hasNext()) {               //遍历每行数据,每个数据都是一个单元格String text = it.next();cell = new PdfPCell(new Phrase(text, textFont));//表头背景色if (i == 0) {cell = new PdfPCell(new Phrase(text, textFontBold));cell.setBackgroundColor(new BaseColor(199, 217, 241));}cell.setMinimumHeight(17); //设置单元格高度cell.setUseAscender(true); //设置可以居中cell.setHorizontalAlignment(i == 0 ? Element.ALIGN_CENTER : Element.ALIGN_LEFT); //表头居中,其余左对齐cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中table.addCell(cell);}}doc.add(table);}public static void TableNoAfter(int total, Font textFont, List<List<String>> data, Document doc) throws DocumentException {// 创建一个有N列的表格PdfPTable table = new PdfPTable(total);table.setPaddingTop(20);table.setTotalWidth(530); //设置列宽table.setLockedWidth(true); //锁定列宽PdfPCell cell;for (int i = 0; i < data.size(); i++) {  //遍历数据行   每个数据行都是一个listIterator<String> it = data.get(i).iterator();while (it.hasNext()) {               //遍历每行数据,每个数据都是一个单元格String text = it.next();cell = new PdfPCell(new Phrase(text, textFont));//表头背景色if (i == 0) {cell = new PdfPCell(new Phrase(text, textFontBold));cell.setBackgroundColor(new BaseColor(199, 217, 241));}cell.setMinimumHeight(17); //设置单元格高度cell.setUseAscender(true); //设置可以居中cell.setHorizontalAlignment(i == 0 ? Element.ALIGN_CENTER : Element.ALIGN_LEFT); //表头居中,其余左对齐cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中table.addCell(cell);}}doc.add(table);}public static void TableNoPadding(int total, Font textFont, List<List<String>> data, Document doc) throws DocumentException {// 创建一个有N列的表格PdfPTable table = new PdfPTable(total);table.setTotalWidth(530); //设置列宽table.setLockedWidth(true); //锁定列宽PdfPCell cell;for (int i = 0; i < data.size(); i++) {  //遍历数据行   每个数据行都是一个listIterator<String> it = data.get(i).iterator();while (it.hasNext()) {               //遍历每行数据,每个数据都是一个单元格String text = it.next();cell = new PdfPCell(new Phrase(text, textFont));cell.setMinimumHeight(17); //设置单元格高度cell.setUseAscender(true); //设置可以居中cell.setHorizontalAlignment(Element.ALIGN_LEFT); //表头居中,其余左对齐cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中table.addCell(cell);}}doc.add(table);}public static void TableNoPaddingTop(int total, Font textFont, List<List<String>> data, Document doc) throws DocumentException {// 创建一个有N列的表格PdfPTable table = new PdfPTable(total);table.setPaddingTop(0.0f);table.setSpacingAfter(0.0f);table.setTotalWidth(530); //设置列宽table.setLockedWidth(true); //锁定列宽PdfPCell cell;for (int i = 0; i < data.size(); i++) {  //遍历数据行   每个数据行都是一个listIterator<String> it = data.get(i).iterator();while (it.hasNext()) {               //遍历每行数据,每个数据都是一个单元格String text = it.next();cell = new PdfPCell(new Phrase(text, textFont));if (i == 0) {cell = new PdfPCell(new Phrase(text, textFontBold));cell.setBackgroundColor(new BaseColor(199, 217, 241));}cell.setMinimumHeight(17); //设置单元格高度cell.setUseAscender(true); //设置可以居中//表头背景色cell.setHorizontalAlignment(i == 0 ? Element.ALIGN_CENTER : Element.ALIGN_LEFT); //表头居中,其余左对齐cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中table.addCell(cell);}}doc.add(table);}public static int appearNumber(String srcText, String findText) {int count = 0;Pattern p = Pattern.compile(findText);Matcher m = p.matcher(srcText);while (m.find()) {count++;}return count;}/*** 生成一个表格** @param total    总列数* @param textFont 字体* @param data     表格数据     X行    Y列* @param doc      PDF文档对象* @throws DocumentException* @author hou_fx*/public static void TableBule(int total, Font textFont, List<List<String>> data, Document doc) throws DocumentException {// 创建一个有N列的表格PdfPTable table = new PdfPTable(total);table.setPaddingTop(20);table.setSpacingAfter(20);table.setTotalWidth(530); //设置列宽table.setLockedWidth(true); //锁定列宽PdfPCell cell;for (int i = 0; i < data.size(); i++) {  //遍历数据行   每个数据行都是一个listint count = 0;for (int j = 0; j < data.get(i).size(); j++) {cell = new PdfPCell(new Phrase(data.get(i).get(j), textFont));//第一个单元格背景色if (count % 2 == 0) {cell = new PdfPCell(new Phrase(data.get(i).get(j), textFontBold));cell.setBackgroundColor(new BaseColor(199, 217, 241));}cell.setMinimumHeight(17); //设置单元格高度cell.setUseAscender(true); //设置可以居中cell.setHorizontalAlignment(Element.ALIGN_LEFT); //左对齐cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中table.addCell(cell);count++;}}doc.add(table);}/*** 生成一个表格** @param total    总列数* @param textFont 字体* @param data     表格数据     X行    Y列* @param doc      PDF文档对象* @param colspan  第几列* @param rowspan  第几行* @param number   跨几列* @throws DocumentException* @author hou_fx*/public static void TableBuleColspan(int total, Font textFont, List<List<String>> data, Document doc, int[] rowspan, int[] colspan, int[] number) throws DocumentException {// 创建一个有N列的表格PdfPTable table = new PdfPTable(total);table.setPaddingTop(20);table.setSpacingAfter(20);table.setTotalWidth(530); //设置列宽table.setLockedWidth(true); //锁定列宽PdfPCell cell;//数组下标int cos = 0;for (int i = 0; i < data.size(); i++) {  //遍历数据行   每个数据行都是一个listint count = 0;for (int j = 0; j < data.get(i).size(); j++) {cell = new PdfPCell(new Phrase(data.get(i).get(j), textFont));//第一个单元格背景色if (j % 2 == 0) {cell = new PdfPCell(new Phrase(data.get(i).get(j), textFontBold));cell.setBackgroundColor(new BaseColor(199, 217, 241)); //173,216,230}cell.setMinimumHeight(17); //设置单元格高度cell.setUseAscender(true); //设置可以居中if (cos < rowspan.length && i == rowspan[cos] - 1 && count == colspan[cos] - 1) {cell.setColspan(number[cos]);//跨单元格cos++;}cell.setHorizontalAlignment(Element.ALIGN_LEFT); //左对齐cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中table.addCell(cell);count++;}}doc.add(table);}/*** 生成一个表格** @param total    总列数* @param textFont 字体* @param data     表格数据     X行    Y列* @param doc      PDF文档对象* @param colspan  第几列 [][] 0 跨列 1 跨行* @param rowspan  第几行 [][] 0 跨列 1 跨行* @param number   跨几列 [][] 0 跨列 1 跨行* @throws DocumentException* @author hou_fx*/public static void TableBlueColRowSpan(int total, Font textFont, List<List<String>> data, Document doc, int[][] rowspan, int[][] colspan, int[][] number) throws DocumentException {// 创建一个有N列的表格PdfPTable table = new PdfPTable(total);table.setPaddingTop(20);table.setSpacingAfter(20);table.setTotalWidth(530); //设置列宽table.setLockedWidth(true); //锁定列宽PdfPCell cell;for (int i = 0, cos = 0, ros = 0; i < data.size(); i++) {for (int j = 0; j < data.get(i).size(); j++) {cell = new PdfPCell(new Phrase(data.get(i).get(j), textFont));if (total != data.get(i).size()) {cell = new PdfPCell(new Phrase(data.get(i).get(j), textFontBold));cell.setBackgroundColor(new BaseColor(199, 217, 241)); //173,216,230}if (data.get(i).get(j).contains("合计") || data.get(i).get(j).contains("总计")) {cell.setBackgroundColor(new BaseColor(79, 129, 189)); //173,216,230}cell.setMinimumHeight(17); //设置单元格高度cell.setUseAscender(true); //设置可以居中cell.setHorizontalAlignment(Element.ALIGN_CENTER); //左对齐cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中if (cos < rowspan[0].length && i == rowspan[0][cos] - 1 && j == colspan[0][cos] - 1) {cell.setColspan(number[0][cos]);cos++;}if (ros < rowspan[1].length && i == rowspan[1][ros] - 1 && j == colspan[1][ros] - 1) {cell.setRowspan(number[1][ros]);ros++;}table.addCell(cell);}}doc.add(table);}/*** 生成一个表格** @param total    总列数* @param textFont 字体* @param data     表格数据     X行    Y列* @param doc      PDF文档对象* @param colspan  第几列* @param rowspan  第几行* @param number   跨几列* @throws DocumentException* @author hou_fx*/public static void TableColspan(int total, Font textFont, List<List<String>> data, Document doc, int[] rowspan, int[] colspan, int[] number) throws DocumentException {// 创建一个有N列的表格PdfPTable table = new PdfPTable(total);table.setPaddingTop(20);table.setSpacingAfter(20);table.setTotalWidth(530); //设置列宽table.setLockedWidth(true); //锁定列宽PdfPCell cell;//数组下标int cos = 0;for (int i = 0; i < data.size(); i++) {  //遍历数据行   每个数据行都是一个listIterator<String> it = data.get(i).iterator();int count = 0;while (it.hasNext()) {               //遍历每行数据,每个数据都是一个单元格cell = new PdfPCell(new Phrase(it.next(), textFont));cell.setMinimumHeight(17); //设置单元格高度cell.setUseAscender(true); //设置可以居中if (cos < rowspan.length && i == rowspan[cos] - 1 && count == colspan[cos] - 1) {cell.setColspan(number[cos]);//跨单元格cos++;}cell.setHorizontalAlignment(Element.ALIGN_LEFT);cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中table.addCell(cell);count++;}}doc.add(table);}public static void TableColspanNo(int total, Font textFont, List<List<String>> data, Document doc, int[] rowspan, int[] colspan, int[] number) throws DocumentException {// 创建一个有N列的表格PdfPTable table = new PdfPTable(total);//设置列宽table.setTotalWidth(530);//锁定列宽table.setLockedWidth(true);PdfPCell cell;//数组下标int cos = 0;for (int i = 0; i < data.size(); i++) {  //遍历数据行   每个数据行都是一个listIterator<String> it = data.get(i).iterator();int count = 0;while (it.hasNext()) {               //遍历每行数据,每个数据都是一个单元格cell = new PdfPCell(new Phrase(it.next(), textFont));cell.setMinimumHeight(17); //设置单元格高度cell.setUseAscender(true); //设置可以居中if (cos < rowspan.length && i == rowspan[cos] - 1 && count == colspan[cos] - 1) {cell.setColspan(number[cos]);//跨单元格cos++;}cell.setHorizontalAlignment(Element.ALIGN_LEFT);cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中table.addCell(cell);count++;}}doc.add(table);}
}

GetData

static class GetData {private final static Map<String, String> desensitizationData = new LinkedHashMap<>();static {desensitizationData.put("EntName", "深圳******有限公司");desensitizationData.put("RegAddress", "深圳市**区******");desensitizationData.put("SocialCreditCode", "9***************1");desensitizationData.put("ESocialCreditCode", "9***************1");desensitizationData.put("EntRegNo", "1*******0");desensitizationData.put("Legal", "***");desensitizationData.put("EntOrgCode", "1********0");desensitizationData.put("ShareholderName", "***");desensitizationData.put("FDDBRXM", "***");desensitizationData.put("FDDBRSFZJHM", "440**************2");desensitizationData.put("FDDBRGDDH", "0755-*******");desensitizationData.put("FDDBRYDDH", "13********0");desensitizationData.put("MemberName", "***");desensitizationData.put("InvestName", "深圳******有限公司");desensitizationData.put("ChangeItem", "***变更");desensitizationData.put("ChangeBefore", "*****");desensitizationData.put("ChangeAfter", "********");desensitizationData.put("AccFundNo", "10*******3");desensitizationData.put("SocialSecurityNo", "1******0");desensitizationData.put("RestrictDesc", "******");desensitizationData.put("PatentName", "******");desensitizationData.put("PubNo", "******");desensitizationData.put("WorkName", "******");desensitizationData.put("RegNum", "******");desensitizationData.put("TrademarkName", "******");desensitizationData.put("RregCode", "******");desensitizationData.put("LicenseNo", "******");desensitizationData.put("CaseReason", "******");desensitizationData.put("CaseNo", "******");desensitizationData.put("CaseName", "******");desensitizationData.put("PunishContent", "******");desensitizationData.put("ViolationCaseNo", "*********");desensitizationData.put("projectName", "*********");desensitizationData.put("WebSite", "*********");desensitizationData.put("Tel", "*********");desensitizationData.put("Phone", "*********");desensitizationData.put("IDNo", "*********");desensitizationData.put("CaseCode", "*********");}public static String get(Map map, Compoent compoent, String key) {List data = Optional.ofNullable((List) map.get(compoent.getValue())).orElse(new ArrayList<>());IMap imap = new IMap();if (data.size() > 0) {if (data.get(0) instanceof JSONObject) {((JSONObject) data.get(0)).forEach(imap::put);}}return Optional.ofNullable(imap.get(key)).orElse("-");}public static String get(Map map, Compoent compoent, String key, boolean desensitization) {List data = Optional.ofNullable((List) map.get(compoent.getValue())).orElse(new ArrayList<>());IMap imap = new IMap();if (data.size() > 0) {if (data.get(0) instanceof JSONObject) {if (desensitization) {((JSONObject) data.get(0)).forEach((k, v) -> {String s = String.valueOf(v);imap.put(k, desensitizationData.getOrDefault(k, s));});} else {((JSONObject) data.get(0)).forEach(imap::put);}}}return Optional.ofNullable(imap.get(key)).orElse("-");}public static List<List<String>> get(Map result, Compoent compoent, String... keys) {List<List<String>> res = new ArrayList<>();Optional.ofNullable(result.get(compoent.getValue())).ifPresent(v -> {if (v instanceof ArrayList) {((ArrayList) v).forEach(o -> {List<String> data = new ArrayList<>();JSONObject item = ((JSONObject) o);for (String key : keys) {data.add(StringUtils.isEmpty(item.getString(key)) ? "-" : item.getString(key));}res.add(data);});}});if (res.size() == 0) {List<String> data = new ArrayList<>();for (int i = 0; i < keys.length; i++) {data.add("");}res.add(data);}return res;}public static List<List<String>> get(Boolean desensitization, Map result, Compoent compoent, String... keys) {List<List<String>> res = new ArrayList<>();Optional.ofNullable(result.get(compoent.getValue())).ifPresent(v -> {if (v instanceof ArrayList) {((ArrayList) v).forEach(o -> {List<String> data = new ArrayList<>();JSONObject item = ((JSONObject) o);for (String key : keys) {if (desensitization) {data.add(StringUtils.isEmpty(item.getString(key)) ? "-" : desensitizationData.get(key) == null ? item.getString(key) : desensitizationData.get(key));} else {data.add(StringUtils.isEmpty(item.getString(key)) ? "-" : item.getString(key));}}res.add(data);});}});if (res.size() == 0) {List<String> data = new ArrayList<>();for (int i = 0; i < keys.length; i++) {data.add("");}res.add(data);}return res;}public static List<List<String>> get(Map result, Predicate<JSONObject> predicate, Compoent compoent, String... keys) {List<List<String>> res = new ArrayList<>();Optional.ofNullable(result.get(compoent.getValue())).ifPresent(v -> {if (v instanceof ArrayList) {((ArrayList) v).stream().filter(predicate).forEach(o -> {List<String> data = new ArrayList<>();JSONObject item = ((JSONObject) o);for (String key : keys) {data.add(StringUtils.isEmpty(item.getString(key)) ? "-" : item.getString(key));}if (data.size() == 0) {List<String> row = new ArrayList<>();for (int i = 0; i < keys.length; i++) {row.add("");}data.addAll(row);}res.add(data);});}});return res;}public static List<Map> getListMap(Map result, Compoent compoent, String... keys) {List<Map> data = new ArrayList<>();Optional.ofNullable(result.get(compoent.getValue())).ifPresent(v -> {if (v instanceof ArrayList) {((ArrayList) v).forEach(o -> {JSONObject item = ((JSONObject) o);Map map = new LinkedHashMap(16);for (String key : keys) {map.put(key, StringUtils.isEmpty(item.getString(key)) ? "-" : item.getString(key));}data.add(map);});}});return data;}
}

RowData

static class RowData {public static List<String> add(String... cells) {return Arrays.asList(cells);}public static List<String> add(String cells, List<String> datas) {datas.add(0, cells);return datas;}public static List<String> add(String cells, Map<String, String> data, Function<Map<String, String>, List<String>> func) {List<String> res = func.apply(data);res.add(0, cells);return res;}public static List<List<String>> add(Map<String, List<Map>> data, Function<Map<String, List<Map>>, List<List<String>>> func) {List<List<String>> res = func.apply(data);return res;}
}

TableDataUtil

static class TableDataUtil {public List<List<String>> data = new ArrayList<>();public TableDataUtil add(List<String> rowData) {if (rowData != null && rowData.size() > 0) {data.add(rowData);}return this;}public TableDataUtil addList(List<List<String>> rowData) {data.addAll(rowData);return this;}public List<List<String>> toList() {return data;}public TableDataUtil add(Map<String, List<Map>> data, Function<Map<String, List<Map>>, List<List<String>>> res) {this.data.addAll(res.apply(data));return this;}
}

ChartUtil

static class ChartUtil {private static final Color[] BAR_COLORS = new Color[]{new Color(79, 129, 189),new Color(192, 80, 77),new Color(155, 187, 89),new Color(128, 100, 162),new Color(75, 172, 198),new Color(247, 150, 70),new Color(119, 44, 42),new Color(77, 59, 98),new Color(182, 87, 8),};private static final Color[] LINE_COLORS = new Color[]{new Color(90, 154, 213),new Color(237, 123, 46),new Color(155, 187, 89),};private static final Color[] PIE_COLORS = new Color[]{new Color(79, 129, 189),new Color(192, 80, 77),new Color(155, 187, 89),new Color(128, 100, 162),new Color(75, 172, 198),new Color(247, 150, 70),new Color(119, 44, 42),new Color(77, 59, 98),new Color(182, 87, 8),};private static StandardChartTheme initChartTheme() {StandardChartTheme currentTheme = new StandardChartTheme("JFree");currentTheme.setLargeFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 15));currentTheme.setRegularFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 13));currentTheme.setExtraLargeFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 20));currentTheme.setPlotBackgroundPaint(new Color(255, 255, 204, 0));currentTheme.setPlotOutlinePaint(new Color(0, 0, 0, 0));currentTheme.setRangeGridlinePaint(new Color(78, 74, 74));return currentTheme;}/*** 线图** @param title             标题* @param categoryAxisLabel 分类标签* @param valueAxisLabel    数值标签* @param dataset           数据集* @return org.jfree.chart.JFreeChart* @author Hou_fx* @date 2021.8.4 10:39*/public static JFreeChart lineChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset) {ChartFactory.setChartTheme(initChartTheme());JFreeChart chart = ChartFactory.createLineChart(title,categoryAxisLabel,valueAxisLabel,dataset,PlotOrientation.VERTICAL,true,true,false);CategoryPlot plot = chart.getCategoryPlot();LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();renderer.setDefaultItemLabelsVisible(true);renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());for (int i = 0; i < dataset.getRowKeys().size(); i++) {if (i > LINE_COLORS.length - 1) {renderer.setSeriesPaint(i, new Color(RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200)));} else {renderer.setSeriesPaint(i, LINE_COLORS[i]);}}return chart;}public static JFreeChart lineChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset, CategoryLabelPositions position) {ChartFactory.setChartTheme(initChartTheme());JFreeChart chart = ChartFactory.createLineChart(title,categoryAxisLabel,valueAxisLabel,dataset,PlotOrientation.VERTICAL,true,true,false);CategoryPlot plot = chart.getCategoryPlot();plot.getDomainAxis().setCategoryLabelPositions(position);LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();renderer.setDefaultItemLabelsVisible(true);renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());for (int i = 0; i < dataset.getRowKeys().size(); i++) {if (i > LINE_COLORS.length - 1) {renderer.setSeriesPaint(i, new Color(RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200)));} else {renderer.setSeriesPaint(i, LINE_COLORS[i]);}}return chart;}/*** 柱状图** @param title* @param categoryAxisLabel* @param valueAxisLabel* @param dataset           数据集* @return org.jfree.chart.JFreeChart* @author Hou_fx* @date 2021.8.4 14:03*/public static JFreeChart barChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset) {ChartFactory.setChartTheme(initChartTheme());JFreeChart chart = ChartFactory.createBarChart(title,categoryAxisLabel,valueAxisLabel,dataset,PlotOrientation.VERTICAL,true,true,false);CategoryPlot plot = chart.getCategoryPlot();BarRenderer renderer = (BarRenderer) plot.getRenderer();renderer.setBarPainter(new StandardBarPainter());renderer.setDefaultItemLabelsVisible(true);renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());renderer.setItemMargin(0.0);for (int i = 0; i < dataset.getRowKeys().size(); i++) {if (i > BAR_COLORS.length - 1) {renderer.setSeriesPaint(i, new Color(RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200)));} else {renderer.setSeriesPaint(i, BAR_COLORS[i]);}}return chart;}public static JFreeChart barChart2(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset, DefaultCategoryDataset dataset2, String format2) {ChartFactory.setChartTheme(initChartTheme());JFreeChart chart = ChartFactory.createBarChart(title,categoryAxisLabel,valueAxisLabel,dataset,PlotOrientation.VERTICAL,true,true,false);CategoryPlot plot = chart.getCategoryPlot();NumberAxis axis = new NumberAxis();axis.setNumberFormatOverride(new DecimalFormat("#,##%"));plot.setRangeAxis(1, axis);plot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_RIGHT);plot.setDataset(1, dataset2);plot.mapDatasetToRangeAxis(1, 1);BarRenderer renderer2 = new BarRenderer();renderer2.setSeriesPaint(0, new Color(238, 8, 8, 0));renderer2.setDefaultItemLabelsVisible(true);renderer2.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator(format2, NumberFormat.getInstance()));ItemLabelPosition position1 = new ItemLabelPosition(ItemLabelAnchor.INSIDE12, TextAnchor.TOP_RIGHT);renderer2.setDefaultPositiveItemLabelPosition(position1);plot.setRenderer(1, renderer2);BarRenderer renderer = (BarRenderer) plot.getRenderer();renderer.setBarPainter(new StandardBarPainter());renderer.setDefaultItemLabelsVisible(true);renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());renderer.setItemMargin(0.0);for (int i = 0; i < dataset.getRowKeys().size(); i++) {if (i > BAR_COLORS.length - 1) {renderer.setSeriesPaint(i, new Color(RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200)));} else {renderer.setSeriesPaint(i, BAR_COLORS[i]);}}return chart;}public static JFreeChart barChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset, String format) {ChartFactory.setChartTheme(initChartTheme());JFreeChart chart = ChartFactory.createBarChart(title,categoryAxisLabel,valueAxisLabel,dataset,PlotOrientation.VERTICAL,true,true,false);CategoryPlot plot = chart.getCategoryPlot();BarRenderer renderer = (BarRenderer) plot.getRenderer();renderer.setBarPainter(new StandardBarPainter());renderer.setDefaultItemLabelsVisible(true);renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator(format, NumberFormat.getInstance()));renderer.setItemMargin(0.0);for (int i = 0; i < dataset.getRowKeys().size(); i++) {if (i > BAR_COLORS.length - 1) {renderer.setSeriesPaint(i, new Color(RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200)));} else {renderer.setSeriesPaint(i, BAR_COLORS[i]);}}return chart;}/*** 饼图** @param title* @param dataset* @return org.jfree.chart.JFreeChart* @author Hou_fx* @date 2021.8.4 14:04*/public static JFreeChart pieChart(String title, DefaultPieDataset<String> dataset) {ChartFactory.setChartTheme(initChartTheme());JFreeChart chart = ChartFactory.createPieChart(title,dataset,true,true,false);PiePlot plot = (PiePlot) chart.getPlot();for (int i = 0; i < dataset.getKeys().size(); i++) {if (i > PIE_COLORS.length - 1) {plot.setSectionPaint(dataset.getKey(i), new Color(RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200), RandomUtils.nextInt(110, 200)));} else {plot.setSectionPaint(dataset.getKey(i), PIE_COLORS[i]);}}plot.setDefaultSectionOutlinePaint(new Color(255, 255, 255));plot.setDefaultSectionOutlineStroke(new BasicStroke(3));//plot.setLabelLinkPaint(new Color(255, 255, 255, 0));plot.setLabelBackgroundPaint(new Color(255, 255, 255, 0));plot.setLabelOutlinePaint(new Color(255, 255, 255, 0));plot.setLabelShadowPaint(new Color(255, 255, 255, 0));plot.setShadowPaint(new Color(255, 255, 255, 0));//plot.setLabelGenerator(new StandardPieSectionLabelGenerator(("{0}{2}"), NumberFormat.getNumberInstance(), new DecimalFormat("0.00%")));plot.setLabelGenerator(new StandardPieSectionLabelGenerator(("{2}"), NumberFormat.getNumberInstance(), new DecimalFormat("0.00%")));return chart;}
}

http://chatgpt.dhexx.cn/article/LfNog7AD.shtml

相关文章

EasyUI Datagrid跨行跨列的需求

常规开发后台管理系统中遇到的列表查询&#xff0c;都是用到最基本的数据网格&#xff0c;不包括单元格合并&#xff0c;多列页眉&#xff0c;冻结列和页脚等需求。类似如下这个列表 实现也很简单&#xff0c;引入相关的js、css文件&#xff0c;html标签定义展示的列&#xff0…

html布局 跨行,3种方案实现跨行或跨列布局

今天要讲解的这个问题是之前一位小伙伴在群里请教的提问,是关于跨行跨列的布局,如下图是他要实现的具体布局,看似是最简单的二维布局,实际透露出整个CSS的发展方向。向前可以考察对兼容性的处理功底,向后可以考察对CSS新特性的洞察能力。可攻可受,攻守兼备。 如果对此问题…

HTML表格属性跨列,HTML表格的使用 与 跨行跨列

表格的基本语法&#xff1a; 第一个单元格的内容第二个单元格的内容第一个单元格的内容第二个单元格的内容 创建表格一般分为下面四个步骤 1.创建表格标签table 2.在表格标签table创建行标签tr可以有多行 3.在第一行标签tr里创建单元格标签th可以创建表格标题 4.在行标签tr里创…

EXCEL 跨列居中

居中到箭头所指的位置。 先选中三个单元格&#xff0c;打开格式&#xff0c;找到对齐里的跨列居中就行。 结果&#xff1a;

redis数据结构应用

介绍redis数据结构应用场景

redis底层都有哪些数据结构?带你了解redis是如何存储数据的

文章目录 写在前面键值对的存储——哈希哈希冲突redis解决哈希冲突过多的方式——rehash 双向链表数组压缩链表压缩链表的连锁更新压缩列表的缺陷整数数组和压缩列表在查找时间复杂度方面并没有很大的优势&#xff0c;那为什么 Redis 还会把它们作为底层数据结构呢&#xff1f;…

redis底层数据结构(redis底层存储结构、源码分析)

文章目录 前言一、redis为什么快&#xff1f;二、redis的底层数据结构2.1、redis的底层存储的扩容机制2.1.1、扩容时间2.1.2、扩容多大2.1.3、扩容后的rehash2.1.4、何时进行rehash2.1.5、俩hashtable访问那个呢&#xff1f; 2.2、redis的key的底层数据类型(sds)2.2.1、sds(Sim…

redis底层数据结构 -String

redis包含5种常用数据结构 String 、List、Hash、Set 、Zset 基础铺垫 以set为例 redis其实可以理解为 K-V数据库&#xff0c;因此对每个键值对都会有一个 dictEntry&#xff0c;里面存储了指向 Key 和 Value 的指针&#xff1b;next 指向下一个 dictEntry&#xff0c;与本 …

Redis-常用数据结构

Redis常用数据结构 Redis提供了一些数据结构供我们往Redis中存取数据&#xff0c;最常用的的有5种&#xff0c;字符串&#xff08;String&#xff09;、哈希(Hash)、列表&#xff08;list&#xff09;、集合&#xff08;set&#xff09;、有序集合&#xff08;ZSET&#xff09…

「Redis数据结构」集合对象(Set)

「Redis数据结构」集合对象&#xff08;Set&#xff09; 文章目录 「Redis数据结构」集合对象&#xff08;Set&#xff09;一、概述二、结构三、编码转换四、小结 一、概述 Set是Redis中的单列集合&#xff0c;其特点为不保证有序性、保证元素唯一、可以求交集、并集、差集。 …

图解redis五种数据结构底层实现

redis有五种基本数据结构&#xff1a;字符串、hash、set、zset、list。但是你知道构成这五种结构的底层数据结构是怎样的吗&#xff1f;今天我们来花费五分钟的时间了解一下。(目前redis版本为3.0.6) 动态字符串SDS SDS是"simple dynamic string"的缩写。redis中所…

redis底层数据结构-List

举例分析 创建列表对象 numbers 列表对象有两种底层实现结构 1.压缩列表(zipList)实现的列表对象 压缩列表(zipList)是Redis为了节省内存而开发的&#xff0c;是由一系列特殊编码的连续内存块组成的顺序型数据结构&#xff0c;一个压缩列表可以包含任意多个节点&#xff08;e…

redis中hash数据结构

目录 hash的数据结构ziplist底层实现字典底层实现扩容缩容 引用 hash的数据结构 hash底层数据结构的实现包括两种&#xff1a;ziplist和字典当保存的所有键值对字符串长度小于 64 字节并且键值对数量小于 512 时使用ziplist &#xff0c;否则使用字典的方式 ziplist底层实现 …

redis的五种数据结构

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、字符串&#xff08;String&#xff09; 1.SDS的定义 2.SDS与C语言中字符串的区别&#xff08;优点&#xff09; 2.1 获取字符串长度 2.2 防止缓冲区的溢…

「Redis数据结构」哈希对象(Hash)

「Redis数据结构」哈希对象&#xff08;Hash&#xff09; 文章目录 「Redis数据结构」哈希对象&#xff08;Hash&#xff09;一、概述二、编码ZipListHashTable 三、编码转换 一、概述 Redis中hash对象是一个string类型的field和value的映射表&#xff0c;hash特别适合用于存储…

Redis底层数据结构(图文详解)

目录 前言 Redis为什么要使用2个对象&#xff1f;两个对象的好处 redisObject对象解析 String 类型 1、int 整数值实现 2、embstr 3、raw List 类型 1、压缩链表&#xff1a;ziplist 2、双向链表&#xff1a;linkedlist 3、快速列表&#xff1a;quicklist Hash …

Redis数据结构之hash

对象类数据的存储如果具有较频繁的更新需求操作会显得笨重&#xff0c;这里我们可以用redis的hash数据类型解决。 一、hash类型 新的存储需求&#xff1a;对一系列存储的数据进行编组&#xff0c;方便管理&#xff0c;典型应用存储对象信息 需要的存储结构&#xff1a;一个存储…

Redis数据结构之Zset

文章目录 一、zset数据结构二、跳表skipList什么是跳表&#xff1f;1.跳表的查找2.跳表的插入3.跳表的删除4.跳表的更新 一、zset数据结构 相比于set&#xff0c;sorted set 增加了一个权重参数 score&#xff0c;使得集合中的元素能够按 score 进行有序排列&#xff0c;还可以…

Redis数据结构有哪些

Redis数据结构有哪些 一、Redis数据结构 一、Redis数据结构 Redis是一种基于内存的数据库&#xff0c;并且提供一定的持久化功能&#xff0c;它是一种键值&#xff08;key-value&#xff09;数据库&#xff0c;使用 key 作为 索引找到当前缓存的数据&#xff0c;并且返回给程序…

「Redis数据结构」压缩列表(ZipList)

「Redis数据结构」压缩列表&#xff08;ZipList&#xff09; 文章目录 「Redis数据结构」压缩列表&#xff08;ZipList&#xff09;一、概述二、结构三、连锁更新问题四、压缩列表的缺陷五、小结参考 ZipList 是一种特殊的“双端链表” &#xff0c;由一系列特殊编码的连续内存…