Java浅析,⽣成OFD⽂件
⾸先我们来看OFD⽂件的⽬录结构,OFD⽂件底层为XML,解析可查看相关⽂档,下⾯简述我了解的:
Doc_1⽂件夹下⾯是主要内容
Pages下⾯存放OFD每个页⾯的XML
简单说明Pages下⾯页⾯信息XML⽂件的标签及属性作⽤
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ofd:Page xmlns:ofd="/2016">
<ofd:Area>
<ofd:PhysicalBox>0 0 209.90291 296.68628</ofd:PhysicalBox>
<ofd:ApplicationBox>0 0 209.90291 296.68628</ofd:ApplicationBox>
<ofd:ContentBox>0 0 209.90291 296.68628</ofd:ContentBox>
</ofd:Area>
<ofd:Content>
<ofd:Layer ID="0">
<ofd:ImageObject ID="7" ResourceID="6" Boundary="0 -0.3528 210.2557 297.0391" CTM="210.2557 0 0 297.0391 0 0"/>
<ofd:TextObject ID="9" Font="8" Size="7.761115550994873" Boundary="47.2723 67.0278 261.0557 15.5222">
<ofd:CGTransform CodePosition="0" CodeCount="17" GlyphCount="17">
<ofd:Glyphs>11738 12862 7255 17457 12235 14764 13842 11859 12078 11931 15952 14729 11465 7256 11113 11465
13610</ofd:Glyphs>
</ofd:CGTransform>
<ofd:TextCode X="0.0" Y="7.7611" DeltaX="7.7611 7.4083 7.4083 7.7611 7.7611 7.7611 7.7611 7.7611 7.7611 7.7611 7.7611 7.7611 8.1139 7.0556 7.7611 7.7611">填充字符填充字符填充字符填充字符填</ofd:TextCode>
</ofd:TextObject>
</ofd:Layer>
</ofd:Content>
</ofd:Page>
ofd:CGTransform:标签内的内容,为⽹站⽣成模板内,Res⽂件夹下的字体⽂件内的检索码,这⾥重点说明,我们通过⽹站得到的模板⽂件,在res⽂件加下⾯存放的字体⽂件只包含你OFD⽂件内存在的⽂字,所以你会发现这个字体⽂件特别⼩,你需要到你电脑的
C:\Windows\Fonts下⾯到你需要的字体⽂件,或者⾃⼰准备也⾏,这样可以保证OFD⽂件在各种环境下查看,打印字体的统⼀然后在l⽂件内设置你⾃⼰准备的字体,(⾃⼰准备的字体需要放到Res⽂件夹下⾯),ofd:CGTransform标签内存在内容(字符码),则去字体⽂件内寻匹配的⽂字,没有则显⽰ofd:TextCode标签内的内容。这我选择使⽤ofd:TextCode显⽰内
容,ofd:CGTransform标签则全部删掉。
字体⽂件设置⽂件 l 如下
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ofd:Res BaseLoc="Res" xmlns:ofd="/2016">
<ofd:Fonts>
<ofd:Font ID="" FontName="CBMOWR+STKaiti" FamilyName="CBMOWR+STKaiti">
<ofd:FontFile>f</ofd:FontFile>
</ofd:Font>
<ofd:Font ID="8" FontName="STKaiti" FamilyName="STKaiti">
<FontFile>font.TTF</FontFile>
</ofd:Font>
</ofd:Fonts>
</ofd:Res>
注意 ofd:Font 标签内的ID属性,页⾯信息XML⽂件内 ofd:TextObject 标签的font属性和此处的id⼀致即可引⽤字体。⾄于ofd:Font标签内的FontName属性则需要填⼊字体正确
的头⽂件信息内的名称.
 重点说明标签 ofd:TextObject
ofd:TextObject 标签下的 Boundary 属性:将ofd:TextObject看作⼀个box,前两个值分别为定位点的坐标,后两个值为X轴和Y轴相对与该定位点的偏移量,ofd:TextObject标签显⽰内容位置与XML⽂件内的顺序⽆关
ofd:TextCode 标签下的 DeltaX 属性:为字符X轴偏移量,显⽰的内容有10个,偏移量最少得设置9个,如果显⽰内容字符数-偏移量数 > 1,则会发⽣字符重叠现象;
使⽤dom4j来操作xml⽂件,测试代码-->
package code;
import java.awt.Font;
import java.awt.FontFormatException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import Matcher;
import Pattern;
import org.apache.Path;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import util.OprationFile;
import util.ZipUtil;
public class CreateElectronicCertification {
/
/ofd⽂件迭代id,不能重复,数据折⾏新增节点设置id
private static int index;
private static int index;
public static void main(String[] args) throws DocumentException, IOException {
Map<String, Object> map = new HashMap<String, Object>();
generateOFD(map);
//OprationFile.deleteFiles(new File(newOFDFileSys));//删除⽣成的⽂件。这⾥⾃⼰操作参数,备份好⽂件,删除不可恢复,    }
public static boolean generateOFD(Map<String,Object> map) throws IOException, DocumentException{
//ofd⽂件模板⽂件夹位置
String resourcesAddress = "E:/OFD_model";//("resourcesAddress");
//不折⾏最⼤字符长度
int lineWide = 19;//("lineWide");
//强制换⾏符
String lineBreak = "/r";//("lineBreak");
//折⾏Y轴偏移量
double Y_offset = 7.7611;//("Y_offset");
//⽣成OFD⽂件存放⽂件夹
String OFDAddress = "E:/";//("OFDAddress");
String modelForIDFileAddress = "/Doc_l";//("modelForIDFileAddress");
//String newFileName = ateGUID();
String newFileName = "OFD";//随机OFD⽂件名
String maxIdAndPagesFile = modelForIDFileAddress;//OFD模板存放MaxID,pageAddress地址的Document位置
String newOFDFileSys = copyModelFileSys(newFileName,resourcesAddress);//拷贝模板⽂件,返回新⽂件路径if(newOFDFileSys.equals("0")){
return false;
}
getMaxId(newOFDFileSys+maxIdAndPagesFile);
//获取页⾯xml⽂件的地址
List<String> pageAddressList = getPagesAddress(newOFDFileSys+maxIdAndPagesFile);
for(String pageAddress: pageAddressList){
pageAddress = newOFDFileSys+"/Doc_1/"+pageAddress;
oprationXmlForDom4j(pageAddress, map, lineBreak, lineWide, Y_offset);
}
String OFDName = newFileName+".ofd";
//电⼦签章,⼆维码等图⽚在此覆盖模板内图⽚
//save(String str);
//去根⽬录压缩(OFD⽂件压缩不能带根⽬录)
ZipUtil.doCompress(newOFDFileSys, OFDAddress+OFDName,newFileName);
return true;
}
//获取page页⾯存放地址
public static List<String> getPagesAddress(String maxIdAndPagesFile) throws DocumentException{
SAXReader reader = new SAXReader();
Document document = ad(new File(maxIdAndPagesFile));
List<Element> list =document.selectNodes("//ofd:Page");//XPath
List<String> pageAddressList = new ArrayList<String>();
for(Element elment:list){
pageAddressList.add(elment.attributeValue("BaseLoc"));
}
return pageAddressList;
}
public static String copyModelFileSys(String newFileName,String resourcesAddress) throws IOException{
String oldFileName = new File(resourcesAddress).getName();
String newOFDFileSys = placeAll(oldFileName, newFileName);
pyDir(resourcesAddress, newOFDFileSys)){
return newOFDFileSys;
}
return "0";
return "0";
}
//获取最⼤id,OFD⽂件,XML内的ID属性类似前端页⾯的元素id,不可重复,这⾥取最⼤的在有新增节点时设置id⽤
public static void getMaxId(String address) throws DocumentException{
SAXReader reader = new SAXReader();
Document document = ad(new File(address));
@SuppressWarnings("unchecked")
List<Node>list=document.selectNodes("//ofd:MaxUnitID");
index = Integer.(0).getText())+1;
}getsavefilename
public static void oprationXmlForDom4j(String fileAddress,Map<String, Object> map,String lineBreak,int lineWide,double Y_offset) throws DocumentException, IOException {
File file = new File(fileAddress);
SAXReader reader = new SAXReader();
Document document = ad(file);
Element root = RootElement();
Element layerElement = root.element("Content").element("Layer");
Iterator iterator = document.selectNodes("//ofd:TextObject").iterator();
List<Element> foldLineLsit = new ArrayList<Element>();
while (iterator.hasNext()) {
Element textObjectElement = (Element) ();
for(String key : map.keySet()){
if((textObjectElement.element("TextCode").getText()).equals(key)){
if(key.equals("fj")){
lineWide = 27;//附记页最⼤⾏长度
}
//--------------------------------------
System.out.println("匹配参数:"+textObjectElement.element("TextCode").getText());
List<String> paramList = new ArrayList<String>();
String boundary= textObjectElement.attributeValue("Boundary");
String[] b_split = boundary.split(" ");
String boundaryStr = "";
Double at_Y_offset = Double.parseDouble(b_split[1]);
String params  = (((key)).trim();
String[] paramGroup = params.split(lineBreak);
//⾃动折⾏
for(int i = 0 ; i<paramGroup.length ; i++){
if(paramGroup[i].length()>lineWide){
int flag = 0;
int g_len = (paramGroup[i].length()+lineWide-1)/lineWide;
for(int li = 0;li<g_len;li++){
if(li+1 == g_len){
paramList.add(paramGroup[i].substring(flag,paramGroup[i].length()));
}else{
paramList.add((paramGroup[i].substring(flag,flag+lineWide)));
}
flag+=lineWide;
}
}else{
paramList.add(paramGroup[i]);
}
}
//配置Y轴偏移量,⾸⾏直接替换参数,折⾏依次添加节点()
for(int i = 0; i < paramList.size(); i++){
String param = (i);
if(i==0){
Element atElem = textObjectElement.element("TextCode");
atElem.setText(param);
}else{
at_Y_offset = Double.parseDouble(String.format("%.4f", at_Y_offset+Y_offset));
boundaryStr = b_split[0]+" "+ at_Y_offset + " " + b_split[2]+ " "+b_split[3];
//setParam(textObjectElement,param,boundaryStr);
/
/setParam(textObjectElement,param,boundaryStr);
Element newElement = (Element) textObjectElement.clone();//此处必须使⽤clone()⽅法,底层调⽤Object的clone();
Element elem = newElement.element("TextCode");
//第三页模板平均折⾏Y轴偏移量7.7611,Boundary第三,四个参数可忽略不设置,⽂件解析根据DeltaX偏移量⾃动布局Boundary宽度,⾼度为定植不⽤修改
index = index+1;
elem.setText(param);
newElement.attribute("ID").setValue(index+"");
newElement.attribute("Boundary").im());
foldLineLsit.add(newElement);
}
}
}
}
}
if(foldLineLsit.size()>0){
for(Element e : foldLineLsit){
layerElement.add((Element)e.clone());
}
}
save(document, fileAddress);
foldLineLsit.clear();
}
public static void save(Document doc, String address) throws IOException {
OutputFormat format = atePrettyPrint();
format.setEncoding("UTF-8");
File file=new File(address);
XMLWriter writer = new XMLWriter(new FileWriter(file), format);
writer.write(doc);
writer.close();
}
}
⼯具类
package util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class OprationFile {
@SuppressWarnings("static-access")
public static boolean copyDir(String sourcePath, String newPath)
throws IOException {
File file = new File(sourcePath);
String[] filePath = file.list();
if (!(new File(newPath)).exists()) {
(new File(newPath)).mkdir();
}
for (int i = 0; i < filePath.length; i++) {
if ((new File(sourcePath + file.separator + filePath[i]))
.isDirectory()) {
copyDir(sourcePath + file.separator + filePath[i], newPath
+ file.separator + filePath[i]);
}
if (new File(sourcePath + file.separator + filePath[i]).isFile()) {

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。