You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中将SAP返回的十六进制串转字节解决Apache POI OOXML报错问题

问题原因
  • 你当前的错误核心是直接对十六进制字符串调用getBytes()方法做转换:该方法是将字符串的每个字符单独编码为字节,比如十六进制中的50会被转为代表字符5的0x35、代表字符0的0x30两个字节,而非你需要的十六进制对应二进制值0x50,最终得到的字节数组完全不是合法的DOCX(ZIP格式)二进制流,因此Apache POI会抛出格式错误。
解决方案

方案1:JDK 17+ 原生实现(无第三方依赖)

JDK 17开始提供了内置的HexFormat工具类,可直接完成十六进制串到字节数组的转换:

// 你的十六进制字符串
String hexStr = "504B030414000600080000002100DFA4D26C5A01000020050000130008025B436F6E74656E745F54797065735D2E786D6C20A2040228A0000200000000000000";
// 十六进制转字节数组
byte[] byteArr = HexFormat.of().parseHex(hexStr);
InputStream fis = new ByteArrayInputStream(byteArr);
return new XWPFDocument(OPCPackage.open(fis));

方案2:低版本JDK 自定义实现(无第三方依赖)

如果你的项目JDK版本低于17,可以自己实现十六进制转字节数组的逻辑:

public static byte[] hexToBytes(String hexStr) {
    int len = hexStr.length();
    byte[] bytes = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        bytes[i / 2] = (byte) ((Character.digit(hexStr.charAt(i), 16) << 4)
                             + Character.digit(hexStr.charAt(i+1), 16));
    }
    return bytes;
}

// 调用示例
byte[] byteArr = hexToBytes(你的十六进制字符串);
InputStream fis = new ByteArrayInputStream(byteArr);
return new XWPFDocument(OPCPackage.open(fis));

方案3:基于Apache Commons Codec实现

如果项目已经引入Apache Commons Codec依赖,可以直接用Hex工具类:

byte[] byteArr = Hex.decodeHex(你的十六进制字符串.toCharArray());
InputStream fis = new ByteArrayInputStream(byteArr);
return new XWPFDocument(OPCPackage.open(fis));
校验小技巧

转换完成后可以先校验字节数组前4个字节,合法的DOCX(ZIP格式)文件头固定为0x50 0x4B 0x03 0x04,和你拿到的十六进制串开头的504B0304对应,只要头匹配就说明转换逻辑正确。

内容的提问来源于stack exchange,提问作者Sherif El Nayad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 21:36:03