xml中的list转为Excel,2中解决方案

今天记录下如何将xml转换为 Excel

1如果你已经安装了office-Excel  是微软的, 直接把你的xml文件打开时选择打开方式,选择Excel打开,此时会自动把xml的内容转换为Excel,  注意wps不可以, 

这里请注意如果数据是0开头可能在转为Excel打开时 会自动把0剔除, 这里可以再xml的第一个数据的0前加一个'   后面的0开头的数据就不会剔除了, 在设置列为文本后再把'替换掉就好了

 我的电脑就是wps这里就不演示了.

 

 

2,如果你跟我一样没有安装正版的office  那么下面就教给你怎么处理  

2.1先简单说一下思路 

   java读取xml文件的内容 ---> 转为document或者 java对象数据(示例选择的方法)  --->组装为csv写出-->另存为Excel--设置文本-->替换字符-done!

具体实现:

先看下数据:  其实想得到的就是 shoplist 每个shop为一行数据

我们希望转为这样的数据:

 

下面直接开始撸代码:

1,新建对应的类, 用来接收转换后的xml           类名就叫XMLData吧

我这里用的是xml->对象的方式,  所以需要用java实体类接收数据并加一些注解来匹配字段, 如果你直接把xml转为document也是可以的,只是填充数据的循环对象不同而已

package net.yto.global.edi.job.notify.orderConsumer;

import lombok.Data;

import javax.xml.bind.annotation.*;
import java.util.List;

@Data
@XmlRootElement(name = "doc")
@XmlAccessorType(XmlAccessType.FIELD)
public class XMLData {
    @XmlElementWrapper(name = "shopList")
    @XmlElement(name = "shop")
    private List<Shop> shops;

    @Data
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Shop {
        private String DepId;
        private String Filial;
        private String States;
    }
}

 2开始写main主运行程序

package net.yto.global.edi.job.notify.orderConsumer;

import net.yto.global.edi.baseinfo.util.MarshallerXmlUtils;
import net.yto.global.edi.common.util.FileUtils;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ming
 */
public class TestXmlData {

    public static void main(String[] args) throws JAXBException, IOException {
        //xml转java对象的上下文 如果在转换时初始化 大量被调用的会影响性能,需要定义为静态的,这里方法值运行一次就写到方法里面了
        JAXBContext SHOPContext = JAXBContext.newInstance(XMLData.class);

        //读取文件内容,这里的E:\\data\\shop.txt 就是上面的截图xml内容
        List<String> strings = FileUtils.readTxtFile("E:\\data\\shop.txt");

        //这里要注意,如果你的xml是经过压缩的,那么你拿到的list的第一个item就是整个xml了,因为上面的方法是按行读取,如果是格式化后的xml需要把每行拼接起来
        //根据你的情况定要不要执行下面的拼接代码
        StringBuilder b = new StringBuilder();
        for (String string : strings) {
            b.append(string.trim());
        }
        //xml转java对象
        XMLData xmlData = MarshallerXmlUtils.xmlToBean(b.toString(), SHOPContext, XMLData.class);
        //将数据整理为csv的格式,我们都知道 csv其实就是逗号分割的文本数据
        List<XMLData.Shop> shopList = xmlData.getShops();

        //csv的表头 这里不写也可以,如果需要后面自己在Excel加
        List<String> header = new ArrayList<>();
        header.add("DepId");
        header.add("Filial");
        header.add("States");
        
        List<String> data = new ArrayList<>();
        //表头
        data.add(String.join(",", header));
        //数据内容 这里在数据的前面加'是方式0开头的数据被自动剔除,所以这里加上了, 逗号替换为|的原因是因为,在csv中逗号是分隔符,所以这里替换为|,后面自己在替换回来即可
        shopList.forEach(e -> {
            List<String> item = new ArrayList<>();
            item.add("'" + (null == e.getDepId() ? "" : e.getDepId().replace(",", "|")));
            item.add("'" + (null == e.getFilial() ? "" : e.getFilial().replace(",", "|")));
            item.add("'" + (null ==e.getStates() ? "" : e.getStates().replace(",", "|")));
            data.add(String.join(",", item));
        });
        //写入文件
        writer("E:\\data\\shop.csv", data, "utf-8", false);
    }

    /**
     * 以指定的编码 写入数据
     */
    private static void writer(String filePath, List<String> content, String charset, boolean append) throws IOException {
        try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(filePath, append), charset);
             BufferedWriter bufferedWriter = new BufferedWriter(writer)) {
            for (String item : content) {
                bufferedWriter.write(item);
                bufferedWriter.newLine();
            }
        }
    }
}

上文中用到的几个方法:

2.1 FileUtils.readTxtFile

读取文本数据--供参考
/**
 * 逐行读取文本
 *
 * @param file
 * @return
 */
public static List<String> readTxtFile(String filePath) throws IOException {
    File file = new File(filePath)
    
    //判断文件是否存在
    if (!file.exists() || !file.isFile()) {
        return null;
    }
    List<String> stringList = new ArrayList<>();
    readLines(Files.newInputStream(file.toPath()), stringList);
    return stringList;
}

/**
     * 读取数据
     *
     * @param inputStream
     * @param stringList
     * @throws IOException
     */
    private static void readLines(InputStream inputStream, List<String> stringList) throws IOException {
        //读取
        try (InputStreamReader read = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
             BufferedReader bufferedReader = new BufferedReader(read)) {
            String lineTxt;
            while (null != (lineTxt = bufferedReader.readLine())) {
                if (StringUtil.isNotEmpty(lineTxt)) {
                    stringList.add(lineTxt);
                }
            }
        } catch (IOException e) {
            log.error("读取文件失败", e);
            throw e;
        }
    }

2.2 MarshallerXmlUtils.xmlToBean

xml-javabean--供参考
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;

/**
 * xml 转为javabean
 *
 * @param xml xml字符串
 * @param t   需要转换的类
 * @param <T> 泛型
 * @return T
 * @throws JAXBException 抛出异常
 */
public static <T> T xmlToBean(String xml, final JAXBContext context, Class<T> t) throws JAXBException {
    Unmarshaller unmarshaller = context.createUnmarshaller();
    StringReader sr = new StringReader(xml);
    T unmarshal = (T) unmarshaller.unmarshal(sr);
    return unmarshal;
}

 

3 运行后我们将会得到一个新的csv文件

 

3.1 下面需要将我们的数据进行一点小小的操作,这个操作就在wps中进行就可以

3.1.1 打开文件:使用wps

3.1.2 另存为Excel

3.1.3 设置列为文本

3.1.4 替换'为 空, 这个是之前为了防止0剔除我们手动加上去的,如果你用了其他字符,就替换其他字符

3.1.5 替换| 为逗号   这个是之前防止数据中的逗号 对csv数据污染临时把数据中的 逗号替换为 |  这里是还原数据

3.1.6 保存  完毕 

 

好了,这里xml转换Excel就大功告成了,   

 

注意事项:

1如果你拿到的文件时比较大的 那么最好不要尝试格式化 会卡死

2如果数据在确实有' 字符那么不建议使用' 来解决数据开头0的问题,因为后面替换' 会把数据中的也一起替换掉 

 

分享结束~~

posted @ 2024-07-08 15:17  loveCrane  阅读(1)  评论(0编辑  收藏  举报