一、ofd格式介绍
国家发布过一份关于ofd编码格式的资料,本来我想传上去的发现资源重复了,你们可以找找看,没有的话留个邮箱,我看到会发给你们的
ofd本质上其实是一个压缩文件,咱们把他当做一个压缩包来处理就好了,思路是先解压,对解压后的文件进行解析处理,解压后是xml文件,java有很多处理xml的类,这里我推荐dom4j,原因是相对来说功能全、速度快,处理完后再进行压缩,保存为ofd格式即可
ofd的阅读器我也有,只是是公司的,不方便共享了,大家可以找网上在线阅读器
二、xml处理工具类
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;/** DOM4J类DOM4J定义了几个Java类。以下是最常见的类:Document - 表示整个XML文档。文档Document对象是通常被称为DOM树。Element - 表示一个XML元素。 Element对象有方法来操作其子元素,它的文本,属性和名称空间。Attribute - 表示元素的属性。属性有方法来获取和设置属性的值。它有父节点和属性类型。Node - 代表元素,属性或处理指令常见DOM4J的方法当使用DOM4J,还有经常用到的几种方法:SAXReader.read(xmlSource)() - 构建XML源的DOM4J文档。Document.getRootElement() - 得到的XML的根元素。Element.node(index) - 获得在元素特定索引XML节点。Element.attributes() - 获取一个元素的所有属性。Node.valueOf(@Name) - 得到元件的给定名称的属性的值。* * */
public class OfdXmlUtil {public static String ids = "";public static String getAttributeIdByPath(String path,String attribute) throws Exception {List<XmlEntity> xmlList = readXmlByPath(path);int mediaId = 0;for (XmlEntity xml : xmlList) {if (xml.getNode().equals(attribute) && xml.getAttributes().get("ID") != null) {mediaId = mediaId>Integer.parseInt(xml.getAttributes().get("ID"))?mediaId:Integer.parseInt(xml.getAttributes().get("ID"));}}String id=String.valueOf(mediaId+1);return id;}public static String getId(Element node, String element) {if(node.getName().equals(element)) {ids = node.valueOf("id");}// 当前节点下面子节点迭代器Iterator<Element> it = node.elementIterator();// 递归遍历while (it.hasNext()) {// 获取某个子节点对象Element e = it.next();// 对子节点进行遍历getId(e, element);}return ids;}public static String getLastIdByElement(String path, String element) throws Exception {File file = new File(path);// 创建saxReader对象SAXReader reader = new SAXReader();Document document = reader.read(file);// 获取根节点元素对象Element node = document.getRootElement();String str = getId(node, element);return str;}/*** * @param path* @return* @throws Exception*/public static List<XmlEntity> readXmlByPath(String path) throws Exception {File file = new File(path);List<XmlEntity> xmlEntities = readXmlByFile(file);return xmlEntities;}/*** @param file* @return* @throws Exception*/public static List<XmlEntity> readXmlByFile(File file) throws Exception {// 创建saxReader对象SAXReader reader = new SAXReader();Document document = reader.read(file);// 获取根节点元素对象Element node = document.getRootElement();List<XmlEntity> xmlEntities = new ArrayList<XmlEntity>();listNodes(node, xmlEntities);return xmlEntities;}/*** 遍历当前节点元素下面的所有(元素的)子节点* * @param node*/public static void listNodes(Element node, List<XmlEntity> xmlEntities) {XmlEntity xmlEntity = new XmlEntity();xmlEntity.setNode(node.getName());// 获取当前节点的所有属性节点List<Attribute> list = node.attributes();// 遍历属性节点Map<String, String> attributeMap = list.stream().collect(Collectors.toMap(Attribute::getName, Attribute::getValue));xmlEntity.setAttributes(attributeMap);if (!(node.getTextTrim().equals(""))) {xmlEntity.setContent(node.getText());}xmlEntities.add(xmlEntity);// 当前节点下面子节点迭代器Iterator<Element> it = node.elementIterator();// 递归遍历while (it.hasNext()) {// 获取某个子节点对象Element e = it.next();// 对子节点进行遍历listNodes(e, xmlEntities);}}// 递归获取当前节点下最后一个节点的元素public static Element getLastElement(Element node) throws Exception {Element node2 = getNextElement(node, 0);if (node2.elements().size() > 0) {node2 = getNextElement(node2, 0);}return node2;}// 获取当前节点下第i个节点的元素public static Element getNextElement(Element e, int i) {e = e.elements().get(i);return e;}/*** 根据节点名获取节点* * @param node*/public static List<Element> getAllEle(Element node, List<Element> elems) {elems.add(node);List<Element> listElement = node.elements();// 所有一级子节点的listfor (Element e : listElement) {// 遍历所有一级子节点getAllEle(e, elems);// 递归}return elems;}/*** 修改、增加xml属性值 元素无重复 不能修改根元素 String elem 需要修改的标签名, String key属性名, String* value修改后的值* * @return* @throws Exception*/public static boolean edit(Document doc, String elem, String key, String value, String outUrl) throws Exception {Element element = doc.getRootElement();// 当前节点下面子节点迭代器Element tmpEle = doc.getRootElement();List<Element> elems = new ArrayList<Element>();List<Element> listElement = getAllEle(element, elems);if (listElement.size() != 0) {for (Element e : listElement) {// 遍历所有一级子节点if (e.getName().equals(elem)) {tmpEle = e;}}}if (tmpEle.isRootElement()) {return false;} else {// 2.通过增加同名属性的方法,修改属性值tmpEle.addAttribute(key, value); // key相同,覆盖;不存在key,则添加// 指定文件输出的位置writer(doc, outUrl);return true;}}/*** 把document对象写入新的文件* * @param document* @throws Exception*/public static void writer(Document document, String url) throws Exception {// 紧凑的格式// OutputFormat format = OutputFormat.createCompactFormat();// 排版缩进的格式OutputFormat format = OutputFormat.createPrettyPrint();// 设置编码format.setEncoding("UTF-8");// 创建XMLWriter对象,指定了写出文件及编码格式// XMLWriter writer = new XMLWriter(new FileWriter(new// File("src//a.xml")),format);XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(new File(url)), "UTF-8"), format);// 写入writer.setEscapeText(false);writer.write(document);// 立即写入writer.flush();// 关闭操作writer.close();}public static void createSignaturesXml(String signs,String signTmp) throws Exception {Document doc1 = new SAXReader().read(new File(signs + "/Signatures.xml"));Element Signatures = doc1.getRootElement();Element Signature = Signatures.addElement("ofd:Signature");Signature.addAttribute("ID", "1");Signature.addAttribute("Type", "Seal");Signature.addAttribute("BaseLoc", signTmp.substring(signTmp.length()-6) + "/Signature.xml");OfdXmlUtil.writer(doc1, signs + "/Signatures.xml");}
}
三、压缩解压缩处理工具类
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;public class ZipUtil {private ZipUtil() {}public static void doCompress(String srcFile, String zipFile) throws Exception {String rootdDirectory = srcFile.split("/")[srcFile.split("/").length - 1]; // 获取根目录名称doCompress(new File(srcFile), new File(zipFile), rootdDirectory);}/*** 文件压缩* * @param srcFile 目录或者单个文件* @param zipFile 压缩后的ZIP文件*/public static void doCompress(File srcFile, File zipFile, String rootdDirectory) throws Exception {ZipOutputStream out = null;try {out = new ZipOutputStream(new FileOutputStream(zipFile));doCompress(srcFile, out, rootdDirectory);} catch (Exception e) {throw e;} finally {out.close();// 记得关闭资源}}public static void doCompress(File file, ZipOutputStream out, String rootdDirectory) throws IOException {doCompress(file, out, "", rootdDirectory);}public static void doCompress(File inFile, ZipOutputStream out, String dir, String rootdDirectory)throws IOException {if (inFile.isDirectory()) {File[] files = inFile.listFiles();if (files != null && files.length > 0) {for (File file : files) {String name = inFile.getName();if (!"".equals(dir)) {name = dir + "/" + name;}ZipUtil.doCompress(file, out, name, rootdDirectory);}}} else {// 将根目录干掉,否则无法打开OFD文件dir = dir.replaceAll(rootdDirectory, "");ZipUtil.doZip(inFile, out, dir);}}public static void doZip(File inFile, ZipOutputStream out, String dir) throws IOException {String entryName = null;if (!"".equals(dir)) {dir = dir.substring(1, dir.length());entryName = dir + "/" + inFile.getName();} else {entryName = inFile.getName();}ZipEntry entry = new ZipEntry(entryName);out.putNextEntry(entry);int len = 0;byte[] buffer = new byte[1024 * 1024];FileInputStream fis = new FileInputStream(inFile);while ((len = fis.read(buffer)) > 0) {out.write(buffer, 0, len);out.flush();}out.closeEntry();fis.close();}
}
package com.koalii.oes.util;import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;/*** @项目名称:meter* @类名称:ZipTools * @类描述:采用zip压缩文件* @创建人:meter* @创建时间:2018年5月4日 上午10:25:09* @版权:Copyright@2018.All Rights Reserved* @version v1.0*/
public class UnzipUtil {/*** 读写zip文件*/private static void write(InputStream inputStream,OutputStream outStream) throws IOException{byte[] data=new byte[4096];int length=0;while((length=inputStream.read(data)) != -1){outStream.write(data,0,length);}outStream.flush();//刷新输出流inputStream.close();//关闭输入流}public static void unzip(String zipFile, String destDir) throws IOException {unzip(new File(zipFile), new File(destDir));}/*** 解压文件n */public static void unzip(File zipFile, File destDir) throws IOException {ZipFile zipOutFile = new ZipFile(zipFile);Enumeration<? extends ZipEntry> entries = zipOutFile.entries();while (entries.hasMoreElements()) {ZipEntry entry = entries.nextElement();if(entry.isDirectory()){File tempFile = new File(destDir.getAbsolutePath()+File.separator+entry.getName());if (!tempFile.exists()) {tempFile.mkdirs();}}else{File tempFile=new File(destDir.getAbsolutePath()+File.separator+entry.getName());checkParentDir(tempFile);FileOutputStream fileOutStream=new FileOutputStream(tempFile);BufferedOutputStream bufferOutStream = new BufferedOutputStream(fileOutStream);write(zipOutFile.getInputStream(entry),bufferOutStream);bufferOutStream.close();fileOutStream.close();}}zipOutFile.close();//关闭zip文件}/*** 验证父目录是否存在,否则创建*/private static void checkParentDir(File file){if(!file.getParentFile().exists()){file.getParentFile().mkdirs();}}}