将xml文件格式的excel并和的工具类
由于工作中的需求,需要将非标准的excel并和(用编辑器打开是xml形式的文件)要求将单独的文件并和显示成页签,并且保留原有的样式,页签名为文件名
我会接收一个List并最终返回一个File
ps:需要dom4j的jar包
代码块
代码块语法遵循标准markdown代码,例如:
public class ExcelMerge {
/**
* 将多个xls并和成一个
* @param list 传入的File集合
*/
public static File listMergeFile(List<File> list){
//将第一个文件作为主文件并将里面的id按规则替换
File mainFile=list.get(0);
Document mainDoc=coverXmlID(mainFile, 0);
//将主文件Worksheet的name换成文件名
Element rootElement=mainDoc.getRootElement();
String mainFileName=mainFile.getName();
mainFileName=mainFileName.substring(0,mainFileName.indexOf("."));
Element rootWorksheet=rootElement.element("Worksheet");
Attribute rootWorksheetAttribute= (Attribute) rootWorksheet.attributes().get(0);
rootWorksheetAttribute.setValue(mainFileName);
//将集合的其它文件更换id并并和到主文件
for(int i=1;i<list.size();i++){
Document subDoc=coverXmlID(list.get(i),i);
Element subRoot=subDoc.getRootElement();
mergeSubDoc(rootElement,subRoot,list.get(i));
}
File file=docCoverFile(mainDoc,mainFile);
return file;
}
/**
* 将Document对象转换成File文件
* @param mainDoc 要转的document对象
* @param mainFile 目标文件对象
* @return
*/
private static File docCoverFile(Document mainDoc, File mainFile) {
ByteArrayInputStream bis=null;
FileOutputStream fos=null;
try {
bis=new ByteArrayInputStream(mainDoc.asXML().getBytes());
fos=new FileOutputStream(mainFile);
byte[] buf=new byte[1024*1024];
int len=0;
while((len=bis.read(buf))!=-1){
fos.write(buf,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
bis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return mainFile;
}
/**
* 子文件并和到主文件
* @param mainDoc
* @param subDoc
* @param file
*/
private static void mergeSubDoc(Element mainDoc, Element subDoc, File file) {
/**1.把style样式复制进去*/
Element mainStylesNode=mainDoc.element("Styles");
List subStyleNode=subDoc.element("Styles").elements("Style");
for(int i=1;i<subStyleNode.size();i++){
Element styleNode= (Element) subStyleNode.get(i);
mainStylesNode.add((Element) styleNode.clone());
}
/**2.把worksheet复制进去*/
String fileName=file.getName();//获取文件名
fileName=fileName.substring(0,fileName.indexOf("."));
Element subWorksheet=subDoc.element("Worksheet");
Attribute subWordsheetAttribute= (Attribute) subWorksheet.attributes().get(0);
subWordsheetAttribute.setValue(fileName);
mainDoc.add((Element) subWorksheet.clone());
}
/**
* 转换ID值,按一定规则替换
* @param file
* @param index
* @return
*/
private static Document coverXmlID(File file,int index) {
Document document=coverDocument(file);
Element root = document.getRootElement();
List nodeList = root.elements();
//遍历根节点下的子节点
for(int i=0;i<nodeList.size();i++){
Element element = (Element) nodeList.get(i);
//找到Styles节点
if("Styles".equalsIgnoreCase(element.getName())){
List styleNodes=element.elements();
//获取所有style节点
for(int j=0;j<styleNodes.size();j++){
Element styleNode= (Element) styleNodes.get(j);
if("Style".equalsIgnoreCase(styleNode.getName())){
//获取属性值
List attrValue=styleNode.attributes();
Attribute attribute= (Attribute) attrValue.get(0);
String newAttrValue="S"+index+"_"+attribute.getValue();
String oldvalue=attribute.getValue();
//替换style中的ss:id值
attribute.setValue(newAttrValue);
//替换cell节点的styleid属性
replaceStyleID(root,oldvalue,newAttrValue);
}
}
}
}
return document;
}
/**
* 替换cell节点中的styleid
* @param document
* @param attrValue
* @param newAttrValue
*/
private static void replaceStyleID(Element document, String attrValue, String newAttrValue) {
//找到xml文件中的所有row节点
Element tablelement=document.element("Worksheet");
tablelement= (Element) tablelement.elements().get(0);
List<Element> rowList=tablelement.elements("Row");
//遍历row节点中的cell节点
for(int i=0;i<rowList.size();i++){
Element rowNode=rowList.get(i);
List<Element> cellNodeList=rowNode.elements("Cell");
for(int j=0;j<cellNodeList.size();j++){
Element cellNode=cellNodeList.get(j);
Attribute cellAttr= (Attribute) cellNode.attributes().get(1);//获取ss:StyleID
//如果和style中的id值相同,替换成新的
if(attrValue.equalsIgnoreCase(cellAttr.getValue())){
cellAttr.setValue(newAttrValue);
}
}
}
}
/**
* file转成dom
* @param file
* @return
*/
private static Document coverDocument(File file){
SAXReader reader=new SAXReader();
Document document=null;
try {
document=reader.read(file);
} catch (Exception e) {
e.printStackTrace();
}
return document;
}
}