Skip to content

Commit

Permalink
修复部分ofd文件格式特殊,用java标准库zip包无法解压的问题。引入apache commons compress来解压
Browse files Browse the repository at this point in the history
  • Loading branch information
NightsLight-hub committed Mar 1, 2022
1 parent 9d32841 commit c0d7a2e
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 41 deletions.
7 changes: 5 additions & 2 deletions ofdrw-converter/src/test/java/OFD2HTMLTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ public class OFD2HTMLTest {
public void convertHtml() {
try {
// 1. 提供文档
Path ofdIn = Paths.get("src/test/resources/n.ofd");
Path htmlOut = Paths.get("target/n.html");
// Path ofdIn = Paths.get("src/test/resources/n.ofd");
// Path htmlOut = Paths.get("target/n.html");
//发票示例.ofd
Path ofdIn = Paths.get("src/test/resources/发票示例.ofd");
Path htmlOut = Paths.get("target/发票示例.ofd/发票示例.html");
// 2. [可选]配置字体,别名,扫描目录等
// FontLoader.getInstance().addAliasMapping(null, "小标宋体", "方正小标宋简体", "方正小标宋简体")
// FontLoader.getInstance().scanFontDir(new File("src/test/resources/fonts"));
Expand Down
39 changes: 24 additions & 15 deletions ofdrw-converter/src/test/java/OFD2IMGTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,31 @@ public class OFD2IMGTest {
public void test() throws IOException {

//为不规范的字体名创建映射
// FontLoader.getInstance()
// .addAliasMapping("仿宋简体", "方正仿宋简体")
// .addAliasMapping("仿宋", "方正仿宋简体")
// .addAliasMapping("小标宋体", "方正小标宋简体")
// .addAliasMapping("KaiTi_GB2312", "楷体");
FontLoader.getInstance();
FontLoader.getInstance()
.addAliasMapping(null, "小标宋体", "方正小标宋简体", "方正小标宋简体")
.addAliasMapping(null, "KaiTi_GB2312", "楷体", "楷体")
.addAliasMapping(null, "楷体", "KaiTi", "KaiTi")

.addSimilarFontReplaceRegexMapping(null, ".*Kai.*", null, "楷体")
.addSimilarFontReplaceRegexMapping(null, ".*Kai.*", null, "楷体")
.addSimilarFontReplaceRegexMapping(null, ".*MinionPro.*", null, "SimSun")
.addSimilarFontReplaceRegexMapping(null, ".*SimSun.*", null, "SimSun")
.addSimilarFontReplaceRegexMapping(null, ".*Song.*", null, "宋体")
.addSimilarFontReplaceRegexMapping(null, ".*MinionPro.*", null, "SimSun");

FontLoader.getInstance().scanFontDir(new File("src/main/resources/fonts"));
FontLoader.setSimilarFontReplace(true);
long start = System.currentTimeMillis();
toPng("src/test/resources/helloworld.ofd", "target/helloworld.ofd");
toPng("src/test/resources/999.ofd", "target/999.ofd");
toPng("src/test/resources/zsbk.ofd", "target/zsbk.ofd");
toPng("src/test/resources/ano.ofd", "target/ano.ofd");
toPng("src/test/resources/文字横向-数科.ofd", "target/文字横向-数科.ofd");
toPng("src/test/resources/z.ofd", "target/z.ofd");
toPng("src/test/resources/不规范资源路径.ofd", "target/不规范资源路径.ofd");
toPng("src/test/resources/V4RideRight.ofd", "target/V4RideRight.ofd");
toPng("src/test/resources/发票示例.ofd", "target/发票示例.ofd");
// toPng("src/test/resources/helloworld.ofd", "target/helloworld.ofd");
// toPng("src/test/resources/999.ofd", "target/999.ofd");
// toPng("src/test/resources/zsbk.ofd", "target/zsbk.ofd");
// toPng("src/test/resources/ano.ofd", "target/ano.ofd");
// toPng("src/test/resources/文字横向-数科.ofd", "target/文字横向-数科.ofd");
// toPng("src/test/resources/z.ofd", "target/z.ofd");
// toPng("src/test/resources/不规范资源路径.ofd", "target/不规范资源路径.ofd");
toPng("src/test/resources/安证通手动盖章.ofd", "target/安证通手动盖章.ofd");
// toPng("src/test/resources/金格信创自动盖章.ofd", "target/金格信创自动盖章.ofd");
// toPng("src/test/resources/发票示例.ofd", "target/发票示例.ofd");
System.out.printf(">> 总计花费: %dms\n", System.currentTimeMillis() - start);
}

Expand Down
28 changes: 18 additions & 10 deletions ofdrw-converter/src/test/java/OFD2PDFTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.ofdrw.converter.FontLoader;
import org.ofdrw.converter.GeneralConvertException;

import java.io.File;
import java.nio.file.Paths;

public class OFD2PDFTest {
Expand All @@ -15,23 +16,30 @@ public void convertPdf() {
// Path src = Paths.get("src/test/resources/zsbk.ofd");
// Path dst = Paths.get("target/zsbk.pdf");

//为不规范的字体名创建映射
FontLoader.getInstance()
.addAliasMapping(null, "小标宋体", "方正小标宋简体", "方正小标宋简体")
.addAliasMapping(null, "KaiTi_GB2312", "楷体", "楷体")
.addAliasMapping(null, "小标宋体", "方正小标宋简体", "方正小标宋简体")
.addAliasMapping(null, "KaiTi_GB2312", "楷体", "楷体")
.addAliasMapping(null, "楷体", "KaiTi", "KaiTi")

.addSimilarFontReplaceRegexMapping(null, ".*Kai.*", null, "楷体")
.addSimilarFontReplaceRegexMapping(null, ".*SimSun.*", null, "SimSun")
.addSimilarFontReplaceRegexMapping(null, ".*Song.*", null, "宋体")
.addSimilarFontReplaceRegexMapping(null, ".*MinionPro.*", null, "SimSun");
.addSimilarFontReplaceRegexMapping(null, ".*Kai.*", null, "楷体")
.addSimilarFontReplaceRegexMapping(null, ".*Kai.*", null, "楷体")
.addSimilarFontReplaceRegexMapping(null, ".*MinionPro.*", null, "SimSun")
.addSimilarFontReplaceRegexMapping(null, ".*SimSun.*", null, "SimSun")
.addSimilarFontReplaceRegexMapping(null, ".*Song.*", null, "宋体")
.addSimilarFontReplaceRegexMapping(null, ".*MinionPro.*", null, "SimSun");

FontLoader.getInstance().scanFontDir(new File("src/main/resources/fonts"));
FontLoader.setSimilarFontReplace(true);

long start = System.currentTimeMillis();
try {
// ConvertHelper.toPdf(src, dst);
// ConvertHelper.toPdf(Paths.get("src/test/resources/signout.ofd"), Paths.get("target/signout.pdf"));
ConvertHelper.toPdf(Paths.get("src/test/resources/zsbk.ofd"), Paths.get("target/zsbk.pdf"));
// ConvertHelper.toPdf(Paths.get("src/test/resources/999.ofd"), Paths.get("target/999.pdf"));
// ConvertHelper.toPdf(Paths.get("src/test/resources/发票示例.ofd"), Paths.get("target/发票示例.pdf"));
ConvertHelper.toPdf(Paths.get("src/test/resources/金格信创自动盖章.ofd"), Paths.get("target/金格信创自动盖章.pdf"));

// ConvertHelper.toPdf(Paths.get("src/test/resources/zsbk.ofd"), Paths.get("target/zsbk.pdf"));
// ConvertHelper.toPdf(Paths.get("src/test/resources/999.ofd"), Paths.get("target/999.pdf"));
System.out.printf(">> 总计花费: %dms\n", System.currentTimeMillis() - start);
} catch (GeneralConvertException e) {
e.printStackTrace();
}
Expand Down
12 changes: 7 additions & 5 deletions ofdrw-converter/src/test/java/OFD2SVGTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.ofdrw.converter.SVGMaker;
import org.ofdrw.reader.OFDReader;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
Expand All @@ -26,6 +27,7 @@ public void test() throws IOException {
FontLoader.getInstance()
.addAliasMapping(null, "小标宋体", "方正小标宋简体", "方正小标宋简体")
.addAliasMapping(null, "KaiTi_GB2312", "楷体", "楷体")
.addAliasMapping(null, "楷体", "KaiTi", "KaiTi")

.addSimilarFontReplaceRegexMapping(null, ".*Kai.*", null, "楷体")
.addSimilarFontReplaceRegexMapping(null, ".*Kai.*", null, "楷体")
Expand All @@ -34,18 +36,18 @@ public void test() throws IOException {
.addSimilarFontReplaceRegexMapping(null, ".*Song.*", null, "宋体")
.addSimilarFontReplaceRegexMapping(null, ".*MinionPro.*", null, "SimSun");

FontLoader.getInstance().scanFontDir(new File("src/main/resources/fonts"));
FontLoader.setSimilarFontReplace(true);


long start = System.currentTimeMillis();
// toSVG("src/test/resources/999.ofd", "target/999.ofd");
// toSVG("src/test/resources/zsbk.ofd", "target/zsbk.ofd");
// toSVG("src/test/resources/ano.ofd", "target/ano.ofd");
// toSVG("src/test/resources/文字横向-数科.ofd", "target/文字横向-数科.ofd");
// toSVG("src/test/resources/z.ofd", "target/z.ofd");
// toSVG("src/test/resources/发票示例.ofd", "target/发票示例.ofd");
toSVG("src/test/resources/signout.ofd", "target/signout.ofd");
toSVG("src/test/resources/n.ofd", "target/n.ofd");
// toSVG("src/test/resources/金格信创自动盖章.ofd", "target/安证通手动盖章.ofd");
toSVG("src/test/resources/发票示例.ofd", "target/发票示例.ofd");
// toSVG("src/test/resources/signout.ofd", "target/signout.ofd");
// toSVG("src/test/resources/n.ofd", "target/n.ofd");

// toPng("src/test/resources/不规范资源路径.ofd", "target/不规范资源路径.ofd");
System.out.printf(">> 总计花费: %dms\n", System.currentTimeMillis() - start);
Expand Down
Binary file not shown.
Binary file not shown.
5 changes: 5 additions & 0 deletions ofdrw-reader/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.20</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion ofdrw-reader/src/main/java/org/ofdrw/reader/OFDReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public OFDReader(Path ofdFile) throws IOException {
}
workDir = Files.createTempDirectory("ofd-tmp-");
// 解压文档,到临时的工作目录
ZipUtil.unZipFiles(ofdFile.toFile(), workDir.toAbsolutePath().toString() + File.separator);
ZipUtil.unZipFileByApacheCommonCompress(ofdFile.toFile(), workDir.toAbsolutePath().toString() + File.separator);
ofdDir = new OFDDir(workDir);
// 创建资源定位器
rl = new ResourceLocator(ofdDir);
Expand Down
50 changes: 42 additions & 8 deletions ofdrw-reader/src/main/java/org/ofdrw/reader/ZipUtil.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package org.ofdrw.reader;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.utils.IOUtils;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

public class ZipUtil {

/**
* 解压许可最大字节数,为了防止 ZIP炸弹攻击
*
* <p>
* 默认值: 100M
*/
private static long MaxSize = 100 * 1024 * 1024;
Expand Down Expand Up @@ -103,11 +107,7 @@ public static void unZipFiles(InputStream src, String descDir) throws IOExceptio
* @throws IOException 文件操作IO异常
*/
public static void unZipFiles(File zipFile, String descDir) throws IOException {

try (InputStream in = new FileInputStream(zipFile)) {
unZipFiles(in, descDir);
}

unZipFileByApacheCommonCompress(zipFile, descDir);
}

/**
Expand All @@ -121,4 +121,38 @@ private static void pathValid(String targetDir, String filePath) throws IOExcept
if (!filePath.startsWith(targetDir))
throw new IOException(String.format("不合法的路径:%s", filePath));
}

/**
* 使用apache common compress库 解压zipFile,能支持更多zip包解压的特性
* @param srcFile 带解压的源文件
* @param descDir 解压到目录
* @throws IOException
*/
public static void unZipFileByApacheCommonCompress(File srcFile, String descDir) throws IOException {
File pathFile = new File(descDir).getCanonicalFile();
if (!pathFile.exists() && !pathFile.mkdirs()) {
throw new IOException("failed to create directory " + pathFile);
}
try (ZipFile zipFile = new ZipFile(srcFile)) {
ZipEntry entry = null;
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
entry = entries.nextElement();
File f = new File(pathFile, entry.getName());
if (entry.isDirectory()) {
if (!f.isDirectory() && !f.mkdirs()) {
throw new IOException("failed to create directory " + f);
}
} else {
File parent = f.getParentFile();
if (!parent.isDirectory() && !parent.mkdirs()) {
throw new IOException("failed to create directory " + parent);
}
try (OutputStream o = Files.newOutputStream(f.toPath())) {
IOUtils.copy(zipFile.getInputStream(entry), o);
}
}
}
}
}
}

0 comments on commit c0d7a2e

Please sign in to comment.