Problem description

The project needs to do Russian internationalization. Some fields in the history code are translated into Russian and some are not. We need to sort out the untranslated Chinese and translate it into Russian.

Thinking about

  1. List all res directories, split into two groups based on whether they contain values-ru (semi-automatic)
  2. Copy Chinese files that need to be translated in “Not included” group (semi-automatic)
  3. Copy fields that need to be translated in the Include group (manual only)
  4. Convert copied XML files for translation into Excel for translation (automatic)
  5. Convert the translated files to XML according to the previously recorded RES directory into the project (semi-automatic)

code

Lists all string.xml file paths

public static void listResPath(String src) throws Exception {
    File path1 = new File(src);
    if(! path1.exists()) {return;
    }

    File[] items = path1.listFiles();
    if (items == null) return;

    for (File item : items) {
        if (item.isFile()) {
            if(! item.getName().equals("strings.xml")) continue;
            System.out.println(item.getPath());
        } else{ listResPath(item.getPath()); }}}Copy the code

Manually find the module that does not contain RU, and then look in the project to see which file should be translated, put the file path to be translated into a TXT, for example:

D:\work\aaa\src\main\res\values-zh-rCN\strings.xml
D:\work\bbb\src\main\res\values-zh-rCN\strings.xml
D:\work\ccc\src\main\res\values\strings.xml
D:\work\ddd\src\main\res\values-zh\strings.xml
Copy the code

Copy these files to the Translate folder


private static List<String> needCopyFiles = new ArrayList<>();

private static void getNeedCopyFiles(a) {
    try {
        FileInputStream inputStream = new FileInputStream("D:\xxx\needCopy.txt");
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String str;
        while((str = bufferedReader.readLine()) ! =null) {
            if(! str.isEmpty()) { needCopyFiles.add(str); } } bufferedReader.close(); }catch(IOException e) { e.printStackTrace(); }}public static void listResPath(String src) throws Exception {
    File path1 = new File(src);
    File path2 = new File("D:\xxx\translate");

    if(! path1.exists()) {return;
    }

    File[] items = path1.listFiles();
    if (items == null) return;

    for (File item : items) {
        if (item.isFile()) {
            if(! item.getName().equals("strings.xml")) continue;
            if (needCopyFiles.contains(item.getPath())) {
                System.out.println(item.getPath());
                FileInputStream fis = new FileInputStream(item);
                String[] dir = item.getPath().split("\ \");
                String fileName = dir[7]+dir[8] +".xml";
                FileOutputStream fos = new FileOutputStream(path2 + File.separator + fileName);
                byte[] b = new byte[1024];
                for (int i=0; (i=fis.read(b))! = -1;) {
                    fos.write(b,0,i); fos.flush(); } fos.close(); fis.close(); }}else{ listResPath(item.getPath()); }}}Copy the code

Manually locate the module that contains ru, see in the project which fields need to be translated, copy these fields into a new XML file, and place these XML files in the Translate folder as well.

Read files from the Translate folder into Excel

import com.alibaba.excel.EasyExcel;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.*;

public class Strings2Excel {

    private static final List<ExcelDataBean> excelDataBeanList = new ArrayList<>();

    public static void main(String[] args) {
        try {
            traverseFile("D:\xxx\translate");
            write2Excel();
        } catch(Exception e) { e.printStackTrace(); }}private static void write2Excel(a) {
        String dst = "D:\xxx\res.xlsx";
        System.out.println("excel list size: " + excelDataBeanList.size());
        EasyExcel.write(dst, ExcelDataBean.class).sheet("value").doWrite(excelDataBeanList);
    }

    public static void traverseFile(String src) throws Exception {
        File path1 = new File(src);

        if(! path1.exists()) { System.out.println("Source path does not exist");
            return;
        }

        File[] items = path1.listFiles();
        if (items == null) return;
        for(File item : items) { readXml(item); }}private static void readXml(File file) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(file);
        Element rootElement = document.getRootElement();
        Iterator<Element> iterator = rootElement.elementIterator();
        while (iterator.hasNext()) {
            Element child = iterator.next();
            String name = child.attribute(0).getValue();
            String value = child.getStringValue();
            System.out.println(name + "=" + value);
            excelDataBeanList.add(newExcelDataBean(name, value)); }}}Copy the code
public class ExcelDataBean {
    private String name;
    private String value;
    private String translate;

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue(a) {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getTranslate(a) {
        return translate;
    }

    public void setTranslate(String translate) {
        this.translate = translate;
    }

    public ExcelDataBean(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public ExcelDataBean(a) {}}Copy the code

Dependencies to introduce:

<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>2.2.4</version>
    </dependency>

    <! --xls-->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>
    <! -- https://mvnrepository.com/artifact/org.dom4j/dom4j -->
    <dependency>
        <groupId>org.dom4j</groupId>
        <artifactId>dom4j</artifactId>
        <version>2.1.3</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.5</version>
    </dependency>
</dependencies>
Copy the code

Because there may be duplicate Chinese fields in different modules, the translation colleague has to re-translate, so after getting the translated Excel, we need to fill in the duplicate translation. The idea is to read the pre-translated file into excelDataBeanList, read the translated file into translatedList, fill the Russian fields of excelDataBeanList with the same Chinese fields in both lists, and output them to a new file.

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class FillTranslated {

    private static final List<ExcelDataBean> excelDataBeanList = new ArrayList<>();
    private static final List<ExcelDataBean> translatedList = new ArrayList<>();

    public static void main(String[] args) {
        try {
            readRes("D:\xxx\res.xlsx");
        } catch(Exception e) { e.printStackTrace(); }}private static void readRes(String s) {
        File file = new File(s);
        EasyExcel.read(file, ExcelDataBean.class, new AnalysisEventListener<ExcelDataBean>() {

            @Override
            public void invoke(ExcelDataBean bean, AnalysisContext analysisContext) {
                excelDataBeanList.add(bean);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                readTranslated("D:\xxx\translated.xlsx");
            }
        }).sheet().doRead();
    }

    private static void readTranslated(String s) {
        File file = new File(s);
        // This read is actually read by column, not by column title and class attribute name
        EasyExcel.read(file, ExcelDataBean.class, new AnalysisEventListener<ExcelDataBean>() {

            @Override
            public void invoke(ExcelDataBean bean, AnalysisContext analysisContext) {
                translatedList.add(bean);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                fillTranslated();
                write2Excel();
            }
        }).sheet().doRead();
    }

    private static void fillTranslated(a) {
        for (ExcelDataBean bean : translatedList) {
            excelDataBeanList.forEach(a -> {
                if(a.getValue() ! =null&& a.getValue().equals(bean.getValue())) { a.setTranslate(bean.getTranslate()); }}); }}private static void write2Excel(a) {
        String dst = "D:\ XXX \ XLSX";
        System.out.println("excel list size: " + excelDataBeanList.size());
        EasyExcel.write(dst, ExcelDataBean.class).sheet("value").doWrite(excelDataBeanList); }}Copy the code

Convert Excel to XML

Column A B C H K
name value translate Double quotes for name Concatenate strings in XML
detail_up Pack up б р а т ь =""""&A2&"""" ="<string name="&H2&">"&C2&"</string>"