package com.dsideal.base.Tools.Test; import com.dsideal.base.Tools.FillData.ExcelKit.ExcelKit; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.File; import java.util.*; public class TestXml { public static void main(String[] args) throws DocumentException { String xml = "D:\\dsWork\\YunNanDsBase\\src\\main\\java\\com\\dsideal\\base\\Tools\\Test\\Sample.xml"; //3、开始读取 // 创建 SAXReader 对象,读取 XML 文件 SAXReader reader = new SAXReader(); Document document = reader.read(new File(xml)); // 获取根元素 Element root = document.getRootElement(); //折线图 //将xml用IDEA打开,搜索关键的数据值,然后右键查看XPATH完整路径可以获取到下面的路径 ///c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser/c:cat/c:numRef/c:numCache/c:pt/c:v //声明一个数组,图表的所有类型 String[] CHART_TYPES = {"lineChart", "barChart"};//折线,柱状 List> tList = new ArrayList<>(); List children = root.element("chart").element("plotArea").elements();//工作区 List xList = new ArrayList<>(); for (Element child : children) { //将CHART_TYPES数组转换为List List CHART_TYPES_LIST = Arrays.asList(CHART_TYPES); if (CHART_TYPES_LIST.contains(child.getName())) {//如果当前遍历到的子元素是折线图或者柱状图 //System.out.println("找到图表类型:" + child.getName()); String type = child.getName(); Element ce = root.element("chart").element("plotArea").element(type); for (int i = 0; i < ce.elements("ser").size(); i++) { Element ser = ce.elements("ser").get(i); //cat 标签 Element cat = ser.element("cat"); Element numRef = cat.element("numRef"); //数据 Element numCache = numRef.element("numCache"); //多个数据组,xList一定是一样的,并且它是最全的 if (xList.isEmpty()) { xList = numCache.elements("pt"); //构造横向的年份列表 List yearList = new ArrayList<>(); for (Element pt : xList) { String v = pt.element("v").getText(); yearList.add(v); } //添加到横向的表中 tList.add(yearList); } //====================================================== //val标签 Element val = ser.element("val"); numRef = val.element("numRef"); numCache = numRef.element("numCache"); List yList = numCache.elements("pt"); //将客观存在的索引号保存到HashMap中 Map existsMap = new HashMap<>(); for (Element pt : yList) { String idx = pt.attribute("idx").getValue(); String v = pt.element("v").getText(); // 保留两位小数 try { double d = Double.parseDouble(v); if (d == (int) d) { v = String.valueOf((int) d); } else { v = String.format("%.2f", d); } } catch (Exception err) { //do nothing } //是不是有效的,存在的数据,因为有的数据是未填写的 if (!existsMap.containsKey(idx)) { existsMap.put(idx, v); } } //枚举一遍全的xList List vList = new ArrayList<>(); //首行就是年份行,它的size()就是标准宽度 for (int j = 0; j < tList.getFirst().size(); j++) { vList.add(existsMap.getOrDefault(String.valueOf(j), null)); } tList.add(vList); } } } //下面要实现行与列的转置 // 创建一个一维列表,用于存储转换后的列 List> transposed = new ArrayList<>(); //上面生成的数据格式需要行转列,横坐标是年份,纵坐标是数据 int rowCount = tList.size();// 计算行数和列数 int colCount = tList.getFirst().size(); // 遍历每一列 for (int col = 0; col < colCount; col++) { // 创建一个新的内部列表,用于存储当前列的所有行 List column = new ArrayList<>(); // 遍历每一行,将当前列的值添加到新的内部列表中 for (int row = 0; row < rowCount; row++) { String x = tList.get(row).get(col); column.add(x); } // 将当前列添加到结果列表中 transposed.add(column); } //输出转置后的数据 ExcelKit.printTable(transposed); } }