【问题标题】:How to set different currency in different cell depending on currency code如何根据货币代码在不同的单元格中设置不同的货币
【发布时间】:2021-06-02 07:52:04
【问题描述】:

我正在尝试使用 Apache POI 在不同的单元格中设置不同的货币。

我有 JSON 数据:

{
    "data": {
        "shop1": [
            {
                "sku": "sku1",
                "quantity": 1,
                "sale": "100",
                "currency": "USD",
                "cost": 500
            },
            {
                "sku": "sku2",
                "quantity": 1,
                "sale": "100",
                "currency": "USD",
                "cost": 500
            }
        ],
        "shop2": [
            {
                "sku": "sku1",
                "quantity": 1,
                "sale": "100",
                "currency": "COP",
                "cost": 500
            }
        ]
    }
}

我想得到这样的结果(Excel 数据):

shop sku quantity sale cost CNY
shop1 sku1 1 $100.00 ¥500.00
shop1 sku2 1 $1,000,000.00 ¥50,000,000.00
shop2 sku1 1 COP 100.00 ¥500.00

我希望它根据 JSON data.shop1[0].currency 显示不同的货币符号,例如 CNY show ¥USD show $

所以我尝试了这个:

XSSFCellStyle currency = xssfWorkbook.createCellStyle();
currency.setDataFormat(7);

它失败了,它只显示¥。它似乎根据我的系统所在的位置(中国)解析货币。

然后我尝试了:

String symbol = Currency.getInstance("CNY").getSymbol();
currency.setDataFormat(xssfWorkbook.createDataFormat().getFormat("{SYMBOL}#,#0.00".replace("{SYMBOL}", symbol)));

当我使用CNY 时,似乎没问题:我得到¥123.0,但是当我使用USD 时,它失败了,因为Currency.getInstance("CNY").getSymbol(); 使用系统默认语言环境。

在 Excel 中,我可以通过右键单击单元格 -> 格式化单元格 -> 数字 -> 货币 -> 符号(选择)来设置符号。

如何在 Apache POI 中设置货币?

【问题讨论】:

    标签: java apache-poi currency


    【解决方案1】:

    设置像£#,##0.00 这样的数据格式总是会导致用户定义的数据格式。如果您想使用Excel 货币数据格式,就像使用 Format cells -> Number -> Currency -> Symbol -> 选择,那么你需要知道Excel 在这种情况下存储了什么。这些货币数据格式使用$ 后跟货币符号以及方括号中的Windows Language Code Identifier (LCID) 进行存储。例如:[$£-809]。那是英镑£ 大不列颠及北爱尔兰联合王国LCID 809

    要从ISO 国家代码创建此类格式,需要一张将货币代码映射到Excel LCID 货币代码的地图。不幸的是,据我所知,没有这样的地图可用。所以我们需要从头开始创建它。为此,请创建具有此类货币值的 Excel *.xlsx。然后解压缩*.xlsx(它只是一个ZIP 存档)并查看/xl/styles.xml。在那里你会找到类似的东西:

    <numFmts count="6">
     <numFmt formatCode="[$$-409]#,##0.00" numFmtId="164"/>
     <numFmt formatCode="[$€-407]#,##0.00" numFmtId="165"/>
     <numFmt formatCode="[$¥-804]#,##0.00" numFmtId="166"/>
     <numFmt formatCode="[$₽-419]#,##0.00" numFmtId="167"/>
     <numFmt formatCode="[$£-809]#,##0.00" numFmtId="168"/>
     <numFmt formatCode="[$₺-41F]#,##0.00" numFmtId="169"/>
    </numFmts>
    

    使用这些信息,我们可以创建以下地图:

    static final Map<String, String> currencyCodesExcelLCID = new HashMap<>() {
     {
      put("USD", "[$\u0024-409]");  //[$$-409]
      put("CNY", "[$\u00A5-804]");  //[$¥-804]
      put("EUR", "[$\u20AC-407]");  //[$€-407]
      put("RUB", "[$\u20BD-419]");  //[$₽-419]
      put("GBP", "[$\u00A3-809]");  //[$£-809]
      put("TRY", "[$\u20BA-41F]");  //[$₺-41F]
     }
    };
    

    在创建Excel 单元格时,我们可以使用该映射来获取单元格数据格式所需的LCID 货币代码。

    完整示例:

    import java.io.FileOutputStream;
    
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellUtil;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    
    import java.util.Map;
    import java.util.HashMap;
    
    public class CreateExcelDifferentCurrencies {
    
     static final Map<String, String> currencyCodesExcelLCID = new HashMap<>() {
      {
       put("USD", "[$\u0024-409]");  //[$$-409]
       put("CNY", "[$\u00A5-804]");  //[$¥-804]
       put("EUR", "[$\u20AC-407]");  //[$€-407]
       put("RUB", "[$\u20BD-419]");  //[$₽-419]
       put("GBP", "[$\u00A3-809]");  //[$£-809]
       put("TRY", "[$\u20BA-41F]");  //[$₺-41F]
      }
     };
    
     public static void main(String[] args) throws Exception {
    
      Object[][] data = {
       {"Name", "Code", "Value"},
       {"US Dollar", "USD", 1234.56d},
       {"Euro (Germany)", "EUR", 1234.56d},
       {"Yuan Renminbi", "CNY", 1234.56d},
       {"Russian Ruble", "RUB", 1234.56d},
       {"Pound Sterling", "GBP", 1234.56d},
       {"Turkish Lira", "TRY", 1234.56d},
       {"Not available", "NA", 1234.56d}
      };
    
      XSSFWorkbook workbook = new XSSFWorkbook(); String filePath = "./CreateExcelDifferentCurrencies.xlsx";
      //HSSFWorkbook workbook = new HSSFWorkbook(); String filePath = "./CreateExcelDifferentCurrencies.xls";
    
      DataFormat dataFormat = workbook.createDataFormat();
    
      Sheet sheet = workbook.createSheet();
    
      for (int r = 0; r < data.length; r++) {
       Object[] dataRow = data[r];
       Row row = sheet.createRow(r);
       String currencyCode = "";
       for (int c = 0; c < dataRow.length; c++) {   
        Object value = dataRow[c];
        Cell cell = row.createCell(c);
        if (value instanceof String) {
         cell.setCellValue((String)value);
         if (c == 1) currencyCode = (String)value;
        } else if (value instanceof Double) {
         cell.setCellValue((Double)value);
         String symbolLCID = currencyCodesExcelLCID.getOrDefault(currencyCode, "");
         CellUtil.setCellStyleProperty(cell, CellUtil.DATA_FORMAT, dataFormat.getFormat(symbolLCID + "#,##0.00"));
        }
       }
      }
    
      for (int c = 0; c < data[0].length; c++) {
       sheet.autoSizeColumn(c);
      }
    
      FileOutputStream out = new FileOutputStream(filePath);
      workbook.write(out);
      out.close();
      workbook.close();
     }
    }
    

    【讨论】:

      【解决方案2】:

      在您的情况下,最可靠的解决方案是映射 CODE -&gt; SYMBOL。 只需将Currency.getInstance("CNY").getSymbol(); 替换为codeSymbolMap.get("CNY")

      提供货币代码和符号的完整列表,即here

      private static Map<String, String> codeSymbolMap = new HashMap<String, String>() {
          {
              put("AED", "د.إ");
              put("AFN", "؋");
              put("ALL", "L");
              put("AMD", "֏");
              put("ANG", "ƒ");
              put("AOA", "Kz");
              put("ARS", "$");
              put("AUD", "$");
              put("AWG", "ƒ");
              put("AZN", "₼");
              put("BAM", "KM");
              put("BBD", "$");
              put("BDT", "৳");
              put("BGN", "лв");
              put("BHD", ".د.ب");
              put("BIF", "FBu");
              put("BMD", "$");
              put("BND", "$");
              put("BOB", "$b");
              put("BOV", "BOV");
              put("BRL", "R$");
              put("BSD", "$");
              put("BTC", "₿");
              put("BTN", "Nu.");
              put("BWP", "P");
              put("BYN", "Br");
              put("BYR", "Br");
              put("BZD", "BZ$");
              put("CAD", "$");
              put("CDF", "FC");
              put("CHE", "CHE");
              put("CHF", "CHF");
              put("CHW", "CHW");
              put("CLF", "CLF");
              put("CLP", "$");
              put("CNY", "¥");
              put("COP", "$");
              put("COU", "COU");
              put("CRC", "₡");
              put("CUC", "$");
              put("CUP", "₱");
              put("CVE", "$");
              put("CZK", "Kč");
              put("DJF", "Fdj");
              put("DKK", "kr");
              put("DOP", "RD$");
              put("DZD", "دج");
              put("EEK", "kr");
              put("EGP", "£");
              put("ERN", "Nfk");
              put("ETB", "Br");
              put("ETH", "Ξ");
              put("EUR", "€");
              put("FJD", "$");
              put("FKP", "£");
              put("GBP", "£");
              put("GEL", "₾");
              put("GGP", "£");
              put("GHC", "₵");
              put("GHS", "GH₵");
              put("GIP", "£");
              put("GMD", "D");
              put("GNF", "FG");
              put("GTQ", "Q");
              put("GYD", "$");
              put("HKD", "$");
              put("HNL", "L");
              put("HRK", "kn");
              put("HTG", "G");
              put("HUF", "Ft");
              put("IDR", "Rp");
              put("ILS", "₪");
              put("IMP", "£");
              put("INR", "₹");
              put("IQD", "ع.د");
              put("IRR", "﷼");
              put("ISK", "kr");
              put("JEP", "£");
              put("JMD", "J$");
              put("JOD", "JD");
              put("JPY", "¥");
              put("KES", "KSh");
              put("KGS", "лв");
              put("KHR", "៛");
              put("KMF", "CF");
              put("KPW", "₩");
              put("KRW", "₩");
              put("KWD", "KD");
              put("KYD", "$");
              put("KZT", "₸");
              put("LAK", "₭");
              put("LBP", "£");
              put("LKR", "₨");
              put("LRD", "$");
              put("LSL", "M");
              put("LTC", "Ł");
              put("LTL", "Lt");
              put("LVL", "Ls");
              put("LYD", "LD");
              put("MAD", "MAD");
              put("MDL", "lei");
              put("MGA", "Ar");
              put("MKD", "ден");
              put("MMK", "K");
              put("MNT", "₮");
              put("MOP", "MOP$");
              put("MRO", "UM");
              put("MRU", "UM");
              put("MUR", "₨");
              put("MVR", "Rf");
              put("MWK", "MK");
              put("MXN", "$");
              put("MXV", "MXV");
              put("MYR", "RM");
              put("MZN", "MT");
              put("NAD", "$");
              put("NGN", "₦");
              put("NIO", "C$");
              put("NOK", "kr");
              put("NPR", "₨");
              put("NZD", "$");
              put("OMR", "﷼");
              put("PAB", "B/.");
              put("PEN", "S/.");
              put("PGK", "K");
              put("PHP", "₱");
              put("PKR", "₨");
              put("PLN", "zł");
              put("PYG", "Gs");
              put("QAR", "﷼");
              put("RMB", "¥");
              put("RON", "lei");
              put("RSD", "Дин.");
              put("RUB", "₽");
              put("RWF", "R₣");
              put("SAR", "﷼");
              put("SBD", "$");
              put("SCR", "₨");
              put("SDG", "ج.س.");
              put("SEK", "kr");
              put("SGD", "S$");
              put("SHP", "£");
              put("SLL", "Le");
              put("SOS", "S");
              put("SRD", "$");
              put("SSP", "£");
              put("STD", "Db");
              put("STN", "Db");
              put("SVC", "$");
              put("SYP", "£");
              put("SZL", "E");
              put("THB", "฿");
              put("TJS", "SM");
              put("TMT", "T");
              put("TND", "د.ت");
              put("TOP", "T$");
              put("TRL", "₤");
              put("TRY", "₺");
              put("TTD", "TT$");
              put("TVD", "$");
              put("TWD", "NT$");
              put("TZS", "TSh");
              put("UAH", "₴");
              put("UGX", "USh");
              put("USD", "$");
              put("UYI", "UYI");
              put("UYU", "$U");
              put("UYW", "UYW");
              put("UZS", "лв");
              put("VEF", "Bs");
              put("VES", "Bs.S");
              put("VND", "₫");
              put("VUV", "VT");
              put("WST", "WS$");
              put("XAF", "FCFA");
              put("XBT", "Ƀ");
              put("XCD", "$");
              put("XOF", "CFA");
              put("XPF", "₣");
              put("XSU", "Sucre");
              put("XUA", "XUA");
              put("YER", "﷼");
              put("ZAR", "R");
              put("ZMW", "ZK");
              put("ZWD", "Z$");
              put("ZWL", "$");
          }
      };
      

      【讨论】:

        猜你喜欢
        • 2017-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-12
        • 1970-01-01
        • 2014-04-23
        • 1970-01-01
        相关资源
        最近更新 更多