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.

129 lines
5.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 {
/**
* 将一个小数形式的字符串,转为保留两位小数的字符串
*
* @param v
* @return
*/
public static String doubleWith2f(String v) {
// 保留两位小数
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
}
return v;
}
public static void main(String[] args) throws DocumentException {
String xml = "D:\\dsWork\\YunNanDsBase\\src\\main\\java\\com\\dsideal\\base\\Tools\\Test\\Sample.xml";
// 创建 SAXReader 对象,读取 XML 文件
SAXReader reader = new SAXReader();
Document document = reader.read(new File(xml));
// 获取根元素
Element root = document.getRootElement();
//声明一个数组,图表的所有类型
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();
//保留两位小数的字符串
v = doubleWith2f(v);
//是不是有效的,存在的数据,因为有的数据是未填写的
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>> res = 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);
}
// 将当前列添加到结果列表中
res.add(column);
}
//输出转置后的数据
ExcelKit.printTable(res);
}
}