首页 > 解决方案 > 日文字符的格式问题

问题描述

我们需要使用英语和日语以 TABLE 格式打印到 CONSOLE。但是,我们看到日文字符存在不同的格式问题。如果我们使用英语,它工作正常。我们已经搜索了不同的解决方案,但所有解决方案都可以正常使用英文,但无法使用日文字符。

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

public class Test {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    simpleTable();
  }

  public static void simpleTable() {

    /*
     * leftJustifiedRows - If true, it will add "-" as a flag to format string to make it left
     * justified. Otherwise right justified.
     */
    boolean leftJustifiedRows = false;

    /*
     * Table to print in console in 2-dimensional array. Each sub-array is a row.
     */
    String[][] english = new String[][] {
        {"Entity", "Total", "Extracted", "Validated", "Errors", "Migration", "Errors"},
        {"Device", "John", "Johnson", "45", "", "", ""},
        {"Device Groups", "Tom", "", "35", "", "", ""},
        {"Policies", "Rose", "Johnson", "22", "", "", ""},
        {"Deployments", "Jimmy", "Kimmel", "", "", "", ""},
        {"Duration", "Jimmy", "Kimmel", "", "", "", ""}};
    dispaly(leftJustifiedRows, english);

    System.out.println();
    System.out.println();
    String[][] japanese = new String[][] {
        {"\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3", "\u5408\u8A08", "\u62BD\u51FA",
            "\u691C\u8A3C\u6E08\u307F", "\u30A8\u30E9\u30FC", "\u79FB\u884C\u6E08\u307F",
            "\u30A8\u30E9\u30FC"},
        {"\u30c7\u30d0\u30a4\u30b9", "John", "Johnson", "45", "", "", ""},
        {"\u30C7\u30D0\u30A4\u30B9\u30B0\u30EB\u30FC\u30D7", "Tom", "", "35", "", "", ""},
        {"\u30dd\u30ea\u30b7\u30fc", "Rose", "Johnson", "22", "", "", ""},
        {"\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8", "Jimmy", "Kimmel", "", "", "", ""},
        {"\u671f\u9593", "Tom", "", "35", "", "", ""}};
    dispaly(leftJustifiedRows, japanese);


  }

  private static void dispaly(boolean leftJustifiedRows, String[][] table) {
    /*
     * Calculate appropriate Length of each column by looking at width of data in each column.
     * 
     * Map columnLengths is <column_number, column_length>
     */
    Map<Integer, Integer> columnLengths = new HashMap<>();
    Arrays.stream(table)
        .forEach(a -> Stream.iterate(0, (i -> i < a.length), (i -> ++i)).forEach(i -> {
          if (columnLengths.get(i) == null) {
            columnLengths.put(i, 0);
          }
          if (columnLengths.get(i) < a[i].length()) {
            columnLengths.put(i, a[i].length());
          }
        }));
    System.out.println("columnLengths = " + columnLengths);

    /*
     * Prepare format String
     */
    final StringBuilder formatString = new StringBuilder("");
    String flag = leftJustifiedRows ? "-" : "";
    columnLengths.entrySet().stream()
        .forEach(e -> formatString.append("| %" + flag + e.getValue() + "s "));
    formatString.append("|\n");
    System.out.println("formatString = " + formatString.toString());

    /*
     * Print table
     */
    Stream.iterate(0, (i -> i < table.length), (i -> ++i))
        .forEach(a -> System.out.printf(formatString.toString(), table[a]));
  }
}

输出


编辑2:

我已经更新了代码,如下所示:

Transliterator transliterator = Transliterator.getInstance("Halfwidth-Fullwidth");
    Stream.iterate(0, (i -> i < table.length), (i -> ++i))
        .forEach(a -> System.out.print(transliterator.transliterate(String.format(formatString.toString(), table[a]))));

仍然面临的问题:

新的

标签: java

解决方案


您可以使用零宽度字符(例如:U+200C)将字符串的长度调整为字符串的宽度。

package org.example;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

public class Test {

  public static void main(String[] args) {
    // TODO Auto-generated method stub
    simpleTable();
  }

  public static void simpleTable() {

    /*
     * leftJustifiedRows - If true, it will add "-" as a flag to format string to make it left
     * justified. Otherwise right justified.
     */
    boolean leftJustifiedRows = false;

    /*
     * Table to print in console in 2-dimensional array. Each sub-array is a row.
     */
    String[][] english = new String[][] {
        {"Entity", "Total", "Extracted", "Validated", "Errors", "Migration", "Errors"},
        {"Device", "John", "Johnson", "45", "", "", ""},
        {"Device Groups", "Tom", "", "35", "", "", ""},
        {"Policies", "Rose", "Johnson", "22", "", "", ""},
        {"Deployments", "Jimmy", "Kimmel", "", "", "", ""},
        {"Duration", "Jimmy", "Kimmel", "", "", "", ""}};
    dispaly(leftJustifiedRows, english);

    System.out.println();
    System.out.println();
    String[][] japanese = new String[][] {
        {"\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3", "\u5408\u8A08", "\u62BD\u51FA",
            "\u691C\u8A3C\u6E08\u307F", "\u30A8\u30E9\u30FC", "\u79FB\u884C\u6E08\u307F",
            "\u30A8\u30E9\u30FC"},
        {"\u30c7\u30d0\u30a4\u30b9", "John", "Johnson", "45", "", "", ""},
        {"\u30C7\u30D0\u30A4\u30B9\u30B0\u30EB\u30FC\u30D7", "Tom", "", "35", "", "", ""},
        {"\u30dd\u30ea\u30b7\u30fc", "Rose", "Johnson", "22", "", "", ""},
        {"\u30c7\u30d7\u30ed\u30a4\u30e1\u30f3\u30c8", "Jimmy", "Kimmel", "", "", "", ""},
        {"\u671f\u9593", "Tom", "", "35", "", "", ""}};
    dispaly(leftJustifiedRows, japanese);


  }

  private static void dispaly(boolean leftJustifiedRows, String[][] table) {

      /// ADD ZERO-WIDTH CHARACTERS TO STRINGS ///
      try {
          for (int i=0; i<table.length; i++) {
              for (int j=0; j<table[i].length; j++) {
                  // Get the number of code points
                  int length = table[i][j].length();
                  // Get the width of the string
                  // Windows-31J (Shift-JIS) uses 1 byte for half-width characters
                  // and 2 bytes for full-width characters
                  int width = table[i][j].getBytes("Windows-31J").length;
                  // Add one zero-width character for each full-width character
                  table[i][j] = table[i][j] + "\u200C".repeat(width - length);
              }
          }
      } catch (UnsupportedEncodingException e) {
          throw new RuntimeException(e);
      }
      /// ADD ZERO-WIDTH CHARACTERS TO STRINGS ///

    /*
     * Calculate appropriate Length of each column by looking at width of data in each column.
     *
     * Map columnLengths is <column_number, column_length>
     */
    Map<Integer, Integer> columnLengths = new HashMap<>();
    Arrays.stream(table)
        .forEach(a -> Stream.iterate(0, (i -> i < a.length), (i -> ++i)).forEach(i -> {
          if (columnLengths.get(i) == null) {
            columnLengths.put(i, 0);
          }
          if (columnLengths.get(i) < a[i].length()) {
            columnLengths.put(i, a[i].length());
          }
        }));
    System.out.println("columnLengths = " + columnLengths);

    /*
     * Prepare format String
     */
    final StringBuilder formatString = new StringBuilder("");
    String flag = leftJustifiedRows ? "-" : "";
    columnLengths.entrySet().stream()
        .forEach(e -> formatString.append("| %" + flag + e.getValue() + "s "));
    formatString.append("|\n");
    System.out.println("formatString = " + formatString.toString());

    /*
     * Print table
     */
    Stream.iterate(0, (i -> i < table.length), (i -> ++i))
        .forEach(a -> System.out.printf(formatString.toString(), table[a]));
  }
}

您将得到这样的结果(在 Eclipse 的控制台选项卡上)

截屏

限制:

  • 您的终端需要能够处理 Unicode 字符。
  • 表中的日文字符不包含代理项对。

推荐阅读