目录
1、使用场景与期待完成目标
2、实现过程之中的两种思维方式
3、实现部分关键源码
4、实现的效果展示
4.1 properties文件-->Excel ---> properties文件
4.2 Android(string.xml)文件-->Excel ---> Android(string.xml)文件
4.3、 关于 IOS的Localizable.strings 与Vue PC-web端国际化语言: *.js 转换不在叙述可参考源文件
5、相关的Java文件源码
由于最近所做的项目需要做国际化版本,要求支持简体中文(zh)、英文(en)、法文(fr)。由于此项目涉及到多端(PC-Web、Android、IOS);于是就涉及到多端的国际化资源文件的翻译。
其中翻译文件及资源包含有以下几种类别:
由于前面四类型文件 为了能够快速提供给翻译团队。需要进行如下 多种类型文件与Excel之间的转换,把Excel文件提供给翻译团队自己翻译。然后把翻译完毕的Excel文件反转为前面四种类型的文件。具体如下图所示:
经过上面的文件处理;翻译团队能够只关注自己需要翻译的 中文翻译为其他语言;翻译完毕后能够很快到转换为每种国际化语言对应的文件;能够直接使用。
在进行文件转换的过程之中有两种思维方式:
因为涉及多种类型的文件,主要包括了【vue-(zh.js)、Android(string.xml)、IOS(Localizable.strings)、Java(*.properties)】
由于本人主要分派的任务是转换 Android和Java两种类型文件。于是我本人选择的第二种解决方案,直接选择了dom4j.jar(第三方框架)和POI (3.9以前工程旧版)、以及Jdk自带的读取Properties文件。主要实现方式如下
Android(string.xml) ------- Excel ----->Android(string.xml)
dom4j.jar 读取 Android(string.xml)文件 -------->解析后转换List ------->把Key与Value输出到Excel文件之中
读取到Excel文件之中已经翻译好的内容------->转换到List-------->把对应的内容写回到 Android(string.xml)文件
Java(*.properties) ------- Excel ----->Java(*.properties)
java.util.Properties 读取 Properties(*.properties)文件 -------->解析后转换LinkedHashMap ------->把Key与Value输出到Excel文件之中
读取到Excel文件之中已经翻译好的内容------->转换到LinkedHashMap-------->把对应的内容写回到 Properties(*.properties)文件
我的这种方式能够一次性读取文件信息,直接利用第三方框架直接进行相关文件里面内容进行操作。能够无缝转换和集成。
另外两类型文件:vue-(zh.js) IOS(Localizable.strings) 比较特殊;并且Java之中没有相关针对此类文件的操作的第三方框架。
如果按照直接使用第三方框架操作此类文件方式比较费劲;我的另外一个同事直接利用读取文件行信息方式,针对每一行文件内容进行读取和操作;并且按照要求存入到Excel文件。
public static void readFile(String filePath) {
try (FileReader reader = new FileReader(filePath);
BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言
) {
String line;
//网友推荐更加简洁的写法
List
总结:
利用文件流一行一行读取文件内容;可以操作不限制文件类型之中的文件内容。所以此种解决思路 在读取复杂文件类型和Java之中无针对此类文件操作的第三方框架的文件比较管用(所以解决问题时候也许原始的方法可能针对复杂的情况更加管用哟)。
利用已经有第三方框架(dom4j.jar)等等做相关的文件类型;此种方式比较简洁直观;能够一次性读取文件之中的所有内容;然后按照程序需要进行相关的操作和实现。
本次实战之中发现有个奇特的文件,在读取*.properties 发现读取后的文件内容到List后顺序错乱的。最后发现如下原因:Java 的 Properties 加载属性文件后是无法保证输出的顺序与文件中一致的,因为 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。
最后参考此文章:读配置文件可以保持顺序的 Java Properties 类 实现顺序获得properties 文件之中内容
OrderedProperties 类文件内容
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.Set;
public class OrderedProperties extends Properties {
private static final long serialVersionUID = -4627607243846121965L;
private final LinkedHashSet
PropertiesExcelInterconvert 部分源码
public class PropertiesExcelInterconvert {
LinkedHashMap< String, String > propertiesContentToExcelMap = new LinkedHashMap< String, String >();
//创建一个HashMap,它将存储键和值从xls文件提供
LinkedHashMap excelContentToPropertiesMap = new LinkedHashMap< String, String >();
/**
* 读取 properties文件内容
* @param propertiesFilePath
*/
private void readPropertiesContent(String propertiesFilePath) {
// 创建包含属性路径的文件对象
File propertiesFile = new File(propertiesFilePath);
// 如果属性文件是一个文件,做下面的事情
if(propertiesFile.isFile()){
try{
// 创建一个FileInputStream来加载属性文件
FileInputStream fisProp = new FileInputStream(propertiesFile);
BufferedReader in = new BufferedReader(new InputStreamReader(fisProp, "UTF8"));
// 创建Properties对象并加载 通过FileInputStream将属性键和值赋给它
// 注意事项:默认的Properties
/**
Java 的 Properties 加载属性文件后是无法保证输出的顺序与文件中一致的,
因为 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,
而 Hashtable 是不保证进出顺序的。 此处覆盖原来Properties 写新的 OrderedProperties
*/
Properties properties = new OrderedProperties();
properties.load(in);
Enumeration< Object > keysEnum = properties.keys();
properties.keySet().iterator();
while(keysEnum.hasMoreElements()){
String propKey = (String)keysEnum.nextElement();
String propValue = properties.getProperty(propKey);
Map propItem=new HashMap();
propItem.put(propKey.trim(), propValue.trim());
propertiesContentToExcelMap.put( propKey.trim(),propValue.trim());
}
// 属性键和值,通过fileinputstreamprint HashMap并关闭文件FileInputStream
System.out.println("Properties Map ... \n" + propertiesContentToExcelMap);
fisProp.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}
}
/**
* Properties内容写入Excel之中
* @param excelPath
*/
private void writePropertiesContentToExcelFile(String excelPath) {
HSSFWorkbook workBook = new HSSFWorkbook();
//创建一个名为Properties 的sheet
HSSFSheet worksheet = workBook.createSheet("Properties");
// 在当前sheet中创建第一行
HSSFRow row = worksheet.createRow((short) 0);
//设置列头样式
HSSFCellStyle cellStyle = workBook.createCellStyle();
cellStyle.setFillForegroundColor(HSSFColor.GOLD.index);
cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
HSSFCell cell1 = row.createCell(0);
//设置第一行第一列名称
cell1.setCellValue(new HSSFRichTextString("Keys"));
cell1.setCellStyle(cellStyle);
HSSFCell cell2 = row.createCell(1);
cell2.setCellValue(new HSSFRichTextString("Values"));
cell2.setCellStyle(cellStyle);
//循环把 Properties文件内容一行一行添加到Excel之中
for (String s : propertiesContentToExcelMap.keySet()) {
//在sheet之中每次增加一行
HSSFRow rowOne = worksheet.createRow(worksheet.getLastRowNum() + 1);
// 在此行之中创建两列
HSSFCell cellZero = rowOne.createCell(0);
HSSFCell cellOne = rowOne.createCell(1);
//从map和set之中提取 key和value值
String key;
key = s;
String value = propertiesContentToExcelMap.get(key);
// 把提取的值设置到 Excel之中的列
cellZero.setCellValue(new HSSFRichTextString(key));
cellOne.setCellValue(new HSSFRichTextString(value));
}
try{
FileOutputStream fosExcel;
File fileExcel = new File(excelPath);
fosExcel = new FileOutputStream(fileExcel);
workBook.write(fosExcel);
fosExcel.flush();
fosExcel.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
原来的 properties 文件内容
properties 文件转到Excel之中顺序一致
Excel写回到properties 文件
原始的 Android(string.xml)文件
相互转换的文件
Android(string.xml)文件-->Excel
Excel-->Android(string.xml)文件
备注:由于xml可以挂在多层级结构;建议在配置文件之中只使用一层。
https://github.com/jianxia612/MultiLlanguagesExcelConvert.git