OFD文件用Java修改内部使用的字体Font
利用ofd本质是zip文件,先该名为zip后,其内部的 Doc_0/PublicRes.xml 其实存放的是字体相关 的配置
例如,本代码修改对应的字体为预设支持的字体,以解决预览问题
<?xml version="1.0" encoding="UTF-8"?>
<ofd:Res xmlns:ofd="http://www.ofdspec.org/2016" BaseLoc="Res">
<ofd:Fonts>
<ofd:Font ID="5" FontName="Simsun" FamilyName="Simsun"/>
<ofd:Font ID="58" FontName="宋体" FamilyName="宋体"/>
</ofd:Fonts>
</ofd:Res>
实现代码
package com.demo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.demo.utils.DBUtil;
import com.demo.utils.FileUtils;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
/**
* 修改ofd里面的字体文件
*/
public class TestOfdFontChange {
/**
* @param args
*/
public static void main(String[] args) {
final String FontNameValueA = "Simsun";
final String FamilyNameValueA = "Simsun";//Simsun Times New Roman 楷体 宋体
final String FontNameValueB = "宋体";//最后1个
final String FamilyNameValueB = "宋体";//最后1个
try {
final long s1 = DBUtil.startCount();
final String baseDir = "D://data//";
final String filename1 = "gdyh.ofd";
final String filename2 = "gdyh.zip";
final boolean isOk = renameFile(new File(baseDir ,filename1), baseDir + filename2);
if (!isOk) {System.out.println("ofd-->zip修改失败,文件占用!");return;}
System.out.println("ofd-->zip修改成功!");
final ZipFile zip = new ZipFile(new File(baseDir + filename2));
//遍历ZIP
/**
final List<?> listA = zip.getFileHeaders();//zip里面的文件列表
for (final Object object : listA) {
final FileHeader header = (FileHeader) object;
final String zipEntryName = header.getFileName();//内部文件的名称
System.out.println(zipEntryName);
}**/
//获取指定文件
final FileHeader publicResHeader = zip.getFileHeader("Doc_0/PublicRes.xml");
//
final String xmlPath = copyEntryToLocale(baseDir, "PublicRes.xml", zip, publicResHeader);
System.out.println("从目标ZIP中提取XML:"+xmlPath);
//修改xml
SAXReader saxReader = new SAXReader();
try {
final Document document = saxReader.read(new File(xmlPath));
final String encoding = document.getXMLEncoding();
final Element rootElement = document.getRootElement();
@SuppressWarnings("unchecked")
final List<Element> listFont = rootElement.element("Fonts").elements("Font");
final int len = listFont.size();
for (int i = 0; i < len; i++) {
Element fOne = listFont.get(i);
System.out.println("修改前"+fOne.asXML());
if ((i+1)==len) {//最后一个
fOne.addAttribute("FontName", FontNameValueB);
fOne.addAttribute("FamilyName", FamilyNameValueB);
} else {
fOne.addAttribute("FontName", FontNameValueA);
fOne.addAttribute("FamilyName", FamilyNameValueA);
}
System.out.println("修改后"+fOne.asXML());
}
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(xmlPath), encoding);
document.write(out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("从目标ZIP中提取xml已篡改");
final ZipParameters pram = new ZipParameters();
pram.setIncludeRootFolder(true);
pram.setRootFolderInZip("Doc_0");
pram.setFileNameInZip("PublicRes.xml");
zip.addFile(new File(xmlPath), pram);
System.out.println("目标zip中的xml已被覆盖更新");
//
System.out.println("临时xml已删除"+new File(xmlPath).delete());
//
final boolean isOk1 = renameFile(new File(baseDir + filename2), baseDir + filename1);
System.out.println("zip-->ofd修改成功"+isOk1);
System.out.println(DBUtil.stopCountStr(s1));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* zip局部文件提取
* @param lastDir
* @param fileName
* @param zip
* @param header
* @return
*/
private static String copyEntryToLocale(final String lastDir,final String fileName
,final ZipFile zip, final FileHeader header) {
String lastFullPath = "";
FileUtils.createDirectory(lastDir);
FileOutputStream fos = null;
InputStream is = null;
try {
is = zip.getInputStream(header);
final File file = new File(lastDir, fileName);
fos = new FileOutputStream(file);
final byte[] buff = new byte[1024 * 8];
int len = -1;
while(-1 != (len = is.read(buff))) {
fos.write(buff, 0, len);
}
fos.flush();
lastFullPath = file.getAbsolutePath();
} catch (Exception e) {
lastFullPath = "";
e.printStackTrace();
} finally {
if (null != fos) {
try {
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (null != is) {
try {
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return lastFullPath;
}
/**
* 文件重命名
* @param oldF
* @param fullPath
* @return
*/
private static boolean renameFile(File oldF, String fullPath) {
return oldF.renameTo(new File(fullPath));
}
}
输出结果
ofd-->zip修改成功!
从目标ZIP中提取XML:D:\data\PublicRes.xml
修改前<ofd:Font xmlns:ofd="http://www.ofdspec.org/2016" ID="5" FontName="宋体" FamilyName="宋体"/>
修改后<ofd:Font xmlns:ofd="http://www.ofdspec.org/2016" ID="5" FontName="Simsun" FamilyName="Simsun"/>
修改前<ofd:Font xmlns:ofd="http://www.ofdspec.org/2016" ID="58" FontName="楷体" FamilyName="楷体"/>
修改后<ofd:Font xmlns:ofd="http://www.ofdspec.org/2016" ID="58" FontName="宋体" FamilyName="宋体"/>
从目标ZIP中提取xml已篡改
目标zip中的xml已被覆盖更新
临时xml已删除true
zip-->ofd修改成功true
耗时(秒):0.452