最近开发遇到一种情况是上传SVG文件,但是SVG里面的内容涉及到其他文件夹的内容,于是选择上传zip压缩包,在服务器解压保存到指定目录下,就可以获取到文件的绝对路径,再把子文件夹的图片读取到base64来保存。
代码如下
//对上传是svg文件或者zip文件分别处理 public String unPack(MultipartHttpServletRequest mpRequest) { String svg = ""; //压缩包文件夹目录 String newPath = ""; //SVG文件中 image属性相对路径 String imagePath = ""; //Image 绝对路径 String getImagePath = ""; byte[] buffer; String codebase64; BASE64Encoder encoder = new BASE64Encoder(); String newcodebase64; //获取文件名称,判断是svg文件还是zip文件 filename = mpRequest.getFile("svg").getOriginalFilename().toString(); if (filename != null && filename.endsWith("svg")) { svg = svgToString(mpRequest.getFile("svg")); } else { InputStream imageStream = null; //zip文件就解压保存到服务器 try { //把压缩包解压到指定文件夹 newPath = defaultUnzipPath + "\\" + filename; ZipUtil.unwrap(mpRequest.getFile("svg").getInputStream(), new File(newPath)); //获取该路径下所有文件夹 File[] svgFiles = new File(newPath).listFiles(); for (File file : svgFiles) { //找到第一个SVG文件 if (file.getName().endsWith(".svg")) { //File文件转成 MultipartFile文件 FileItem fileItem = new DiskFileItem("mainFile", Files.probeContentType(file.toPath()), false, file.getName(), (int) file.length(), file.getParentFile()); try (InputStream input = new FileInputStream(file); OutputStream os = fileItem.getOutputStream()) { IOUtils.copy(input, os); MultipartFile mulFile = new CommonsMultipartFile(fileItem); svg = svgToString(mulFile); Document doc = Jsoup.parse(svg); //标签选择器,选择g标签 Elements divs = doc.select("g"); for (Element div : divs) { //选择g标签下的image标签 Elements images = div.select("image"); for (Element element : images) { imagePath = element.attr("xlink:href"); getImagePath = newPath + "\\" + imagePath; imageStream = new FileInputStream(getImagePath); buffer = new byte[imageStream.available()]; imageStream.read(buffer); codebase64 = encoder.encode(buffer); newcodebase64 = "data:image/png;base64," + codebase64; svg = svg.replaceAll(imagePath, newcodebase64); } } } break; } } imageStream.close(); del(newPath); } catch (Exception e) { e.printStackTrace(); } } return svg; } //删除本地目录下的文件和文件夹 public void del(String filepath) throws IOException { File f = new File(filepath);//定义文件路径 if (f.exists() && f.isDirectory()) {//判断是文件还是目录 if (f.listFiles().length == 0) {//若目录下没有文件则直接删除 f.delete(); } else { //若有则把文件放进数组,并判断是否有下级目录 File delFile[] = f.listFiles(); int i = f.listFiles().length; for (int j = 0; j < i; j++) { if (delFile[j].isDirectory()) { del(delFile[j].getAbsolutePath());//递归调用del方法并取得子目录路径 } else { delFile[j].delete();//删除文件 } } } } else { f.delete(); } } //判断SVG编码格式 (Unicode or UTF-8) private String svgToString(MultipartFile multipartFile) { if (multipartFile == null) { return ""; } InputStream inputStream; String str; String code = null; try { inputStream = multipartFile.getInputStream(); code = codeString(inputStream); inputStream = multipartFile.getInputStream(); byte[] bytes = new byte[inputStream.available()]; inputStream.read(bytes); if (code == "Unicode") { str = new String(bytes, "Unicode"); } else if (code == "UTF-16BE") { str = new String(bytes, "UTF-16BE"); } else if (code == "UTF-8") { str = new String(bytes, "UTF-8"); } else { str = new String(bytes, "GBK"); } //str = new String(bytes, "Unicode"); //判断是否已经存在viewBox属性,没有就添加此属性 Document doc = Jsoup.parse(str); Element div = doc.select("svg").first(); String viewBox = div.attr("viewbox"); if (viewBox == null ) { String width = div.attr("width").replaceAll("[a-z]", ";").split(";")[0]; String height = div.attr("height").replaceAll("[a-z]", ";").split(";")[0]; div.attr("viewBox", "0 0 " + width + " " + height); } str = doc.toString(); } catch (IOException e) { throw BaseException.BUTCH_IMPORT_TYPEERROT; } return str; } /** * 判断文件的编码格式 * * @param :file * @return 文件编码格式 * @throws Exception */ private String codeString(InputStream bin) throws IOException { BufferedInputStream bfs = new BufferedInputStream(bin); int p = (bfs.read() << 8) + bfs.read(); String code = null; switch (p) { // case 0xefbb: // code = "UTF-8"; // break; case 0xfffe: code = "Unicode"; break; // case 0xfeff: // code = "UTF-16BE"; // break; default: code = "UTF-8"; } return code; }