文档拆分,处理在线编辑docx文件document.xml内容问题。

This commit is contained in:
wangzhijiang
2024-06-04 17:19:37 +08:00
parent 9afeb3e4b4
commit d009e34d21
2 changed files with 169 additions and 1 deletions
@@ -9,9 +9,11 @@ package com.jero.common.util;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.*;
import java.nio.file.*; import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class FileUtils { public class FileUtils {
@@ -49,5 +51,167 @@ public class FileUtils {
e.printStackTrace(); e.printStackTrace();
} }
} }
/**
* 处理在线编辑文件中,拆分图片,document.xml里面标签问题。
* @return
*/
public static InputStream docxModifier(InputStream inputStream){
InputStream resultIs = null;
// 把文件流转成docx文件。存储到本地临时文件
byte[] buf = new byte[1024 * 8];
String tempFileName = UUIDUtils.randomUUID20();
LOGGER.info("处理docx文件中,document.xml文件标签开始,目录名为:" + tempFileName);
String filePath = "D:\\opt\\splitTempFile\\" + tempFileName + "\\";
String afterFilePath = "D:\\opt\\splitTempFile\\" + tempFileName;
File filePathDir = new File(filePath);
if (!filePathDir.exists()) {
filePathDir.mkdirs();
}
String tempFileUrl = filePath + tempFileName + ".docx";
String unZipFileDir = filePath;
try {
FileOutputStream fileOut = new FileOutputStream(new File(tempFileUrl));
while (true) {
int read = 0;
if (inputStream != null) {
read = inputStream.read(buf);
}
if (read == -1) {
break;
}
fileOut.write(buf, 0, read);
}
// 查看文件获取是否成功
if (fileOut.getFD().valid() == true) {
LOGGER.info("获取文件保存成功");
} else {
LOGGER.info("获取文件失败");
}
fileOut.flush();
fileOut.close();
}catch (Exception ex){
ex.printStackTrace();
LOGGER.error("文件流转成docx存储到本地失败:" + ex.getMessage());
}
// 将docx文件解压。
unpackDocx(tempFileUrl,unZipFileDir);
// 解压完,临时文件就没用了,删掉。
deleteFolders(tempFileUrl);
// 获取document.xml文件,解析该文件。
String documentXmlUrl = unZipFileDir + "\\word\\document.xml";
try {
InputStream documentXmlIs = new FileInputStream(new File(documentXmlUrl));
ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
copyStream(documentXmlIs, xmlOutputStream);
String xmlContent = new String(xmlOutputStream.toByteArray(), "UTF-8");
// 将标签去掉。
xmlContent = xmlContent.replace("<mc:AlternateContent>", "")
.replace("<mc:Choice Requires=\"wpg\">", "")
.replace("</mc:Choice>", "")
.replace("</mc:AlternateContent>", "");
LOGGER.info("去掉标签后的XML内容:" + xmlContent);
// 放回原位。
// 将之前的document.xml文件删掉,创建一个新的document.xml文件。并把替换后的内容写进去。
documentXmlIs.close();
deleteFolders(documentXmlUrl);
FileWriter xmlFileWriter = new FileWriter(documentXmlUrl);
BufferedWriter bufferedWriter = new BufferedWriter(xmlFileWriter);
bufferedWriter.write(xmlContent);
bufferedWriter.close();
}catch (Exception ex){
ex.printStackTrace();
LOGGER.error("处理document.xml文件失败:" + ex.getMessage());
}
// 压缩成docx文件,转成文件流返回。
compressDocx(afterFilePath, tempFileUrl);
try {
resultIs = new FileInputStream(tempFileUrl);
// resultIs.close();
} catch (Exception ex) {
ex.printStackTrace();
LOGGER.error("获取处理完之后的docx失败:" + ex.getMessage());
}
// 删除创建的临时文件
// deleteFolders(filePath);
return resultIs;
}
/**
* 解压docx文件
* @param docxFilePath docx文件路径
* @param destDirPath 解压后的文件夹路径
*/
public static void unpackDocx(String docxFilePath,String destDirPath){
ZipUtil.unZip(new File(docxFilePath), destDirPath);
}
// 辅助方法:复制输入流到输出流
private static void copyStream(InputStream inputStream, OutputStream outputStream) throws IOException {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.flush();
}
/**
* 压缩docx文件
* @param folderPath 文件夹路径
* @param docxFilePath 压缩后的docx文件路径。
*/
public static void compressDocx(String folderPath, String docxFilePath) {
try {
File folder = new File(folderPath);
FileOutputStream fos = new FileOutputStream(docxFilePath);
ZipOutputStream zos = new ZipOutputStream(fos);
addFilesToZip(folder, zos, "");
zos.close();
fos.close();
} catch (Exception ex){
ex.printStackTrace();
LOGGER.error("压缩docx文件失败:" + ex.getMessage());
}
}
public static void addFilesToZip(File folder, ZipOutputStream zos, String parentFolderName) throws IOException {
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
addFilesToZip(file, zos, parentFolderName + file.getName() + "/");
continue;
}
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(file);
zos.putNextEntry(new ZipEntry(parentFolderName + file.getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
}
}
public static void main(String[] args) {
try {
// compressDocx("D:\\opt\\splitTempFile\\GZA688BPVSW4T3Y7YK9K\\","D:\\opt\\splitTempFile\\GZA688BPVSW4T3Y7YK9K\\GZA688BPVSW4T3Y7YK9K.docx");
compressDocx("D:\\opt\\splitTempFile\\GZA688BPVSW4T3Y7YK9K", "D:\\opt\\splitTempFile\\GZA688BPVSW4T3Y7YK9K\\output.docx");
} catch (Exception e) {
e.printStackTrace();
}
}
} }
@@ -237,6 +237,10 @@ public class FileSpiltService {
} }
log.info("下载文档结束========================================================="); log.info("下载文档结束=========================================================");
} }
// 处理在线编辑文件中,图片拆分问题。
splitFileIs = com.jero.common.util.FileUtils.docxModifier(splitFileIs);
//记录公式自动编号 //记录公式自动编号
MathNumber mathNumber = new MathNumber(); MathNumber mathNumber = new MathNumber();
try (InputStream is = splitFileIs;InputStream is1 = splitFileIs1) { try (InputStream is = splitFileIs;InputStream is1 = splitFileIs1) {