You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
5.6 KiB

8 months ago
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<List<String>> tList = new ArrayList<>();
List<Element> children = root.element("chart").element("plotArea").elements();//工作区
List<Element> xList = new ArrayList<>();
for (Element child : children) {
//将CHART_TYPES数组转换为List
List<String> 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<String> 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<Element> yList = numCache.elements("pt");
//将客观存在的索引号保存到HashMap中
Map<String, String> 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<String> 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<List<String>> transposed = new ArrayList<>();
//上面生成的数据格式需要行转列,横坐标是年份,纵坐标是数据
int rowCount = tList.size();// 计算行数和列数
int colCount = tList.getFirst().size();
// 遍历每一列
for (int col = 0; col < colCount; col++) {
// 创建一个新的内部列表,用于存储当前列的所有行
List<String> 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);
}
}