应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换

目录

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文件源码


1、使用场景与期待完成目标

         由于最近所做的项目需要做国际化版本,要求支持简体中文(zh)、英文(en)、法文(fr)。由于此项目涉及到多端(PC-Web、Android、IOS);于是就涉及到多端的国际化资源文件的翻译。

        其中翻译文件及资源包含有以下几种类别:              

  • Java后端程序 i18n的 *.properties 文件 
  • Android国际化语言文件:strings.xml
  • OS国际化语言文件:Localizable.strings
  • Vue PC-web端国际化语言: *.js 的JSON文件
  • DataBase之中包含的字典、基础业务数据需要翻译数据等等。

    由于前面四类型文件 为了能够快速提供给翻译团队。需要进行如下 多种类型文件与Excel之间的转换,把Excel文件提供给翻译团队自己翻译。然后把翻译完毕的Excel文件反转为前面四种类型的文件。具体如下图所示:

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第1张图片

经过上面的文件处理;翻译团队能够只关注自己需要翻译的 中文翻译为其他语言;翻译完毕后能够很快到转换为每种国际化语言对应的文件;能够直接使用。

2、实现过程之中的两种思维方式

       在进行文件转换的过程之中有两种思维方式:

  • 可以使用读取文件流的方式 一行一行处理
  • 使用Java后端相关第三方框架(.jar) 

    因为涉及多种类型的文件,主要包括了【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> list = new ArrayList<>();
          while ((line = br.readLine()) != null) {
             if(line.contains("=")) {
          		Map map = new HashMap();
          		String value[] = line.split("=");
          		String realKey= value[0].trim().replace("\"", "");
          		String realValue= value[1].replace(";", "").replace("\"", "");
          		map.put(realKey, realValue);
          		list.add(map);
          	}
          }
          createExcel(list);//生产EXcel
      } catch (IOException e) {
          e.printStackTrace();
      }
  }

    总结: 

            利用文件流一行一行读取文件内容;可以操作不限制文件类型之中的文件内容。所以此种解决思路 在读取复杂文件类型和Java之中无针对此类文件操作的第三方框架的文件比较管用(所以解决问题时候也许原始的方法可能针对复杂的情况更加管用哟)。

           利用已经有第三方框架(dom4j.jar)等等做相关的文件类型;此种方式比较简洁直观;能够一次性读取文件之中的所有内容;然后按照程序需要进行相关的操作和实现。

           本次实战之中发现有个奇特的文件,在读取*.properties 发现读取后的文件内容到List后顺序错乱的。最后发现如下原因:Java 的 Properties 加载属性文件后是无法保证输出的顺序与文件中一致的,因为 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。

最后参考此文章:读配置文件可以保持顺序的 Java Properties 类 实现顺序获得properties  文件之中内容

3、实现部分关键源码

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 keys = new LinkedHashSet();
 
    public Enumeration keys() {
        return Collections. enumeration(keys);
    }
 
    public Object put(Object key, Object value) {
        keys.add(key);
        return super.put(key, value);
    }
    
    public Set keySet() {
        return keys;
    }
 
    public Set stringPropertyNames() {
        Set set = new LinkedHashSet(); 
        for (Object key : this.keys) {
            set.add((String) key);
        } 
        return set;
    }
} 
  

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(); 
        }
    }
}

4、实现的效果展示

4.1 properties文件-->Excel ---> properties文件

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第2张图片

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第3张图片

原来的 properties 文件内容

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第4张图片

properties 文件转到Excel之中顺序一致

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第5张图片

Excel写回到properties 文件

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第6张图片

4.2 Android(string.xml)文件-->Excel ---> Android(string.xml)文件

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第7张图片

原始的 Android(string.xml)文件

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第8张图片

相互转换的文件

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第9张图片

Android(string.xml)文件-->Excel

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第10张图片

Excel-->Android(string.xml)文件

应用系统 多端不同文件 国际化(i18n) Excel与多种文件之间相互转换_第11张图片

备注:由于xml可以挂在多层级结构;建议在配置文件之中只使用一层。

4.3、 关于 IOS的Localizable.strings 与Vue PC-web端国际化语言: *.js 转换不在叙述可参考源文件

5、相关的Java文件源码

https://github.com/jianxia612/MultiLlanguagesExcelConvert.git

你可能感兴趣的:(日常工具类,话说业务系统功能设计)