Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请问如何在Ubuntu里导出xlsx文件时,文件名支持中文 #395

Open
zhangwx95 opened this issue Oct 23, 2024 · 6 comments
Open

Comments

@zhangwx95
Copy link

导出数据的时候报错如下:看着是中文不支持,在windows下没有这个问题,在docker部署的 Ubuntu22.04下
java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters: MO样例1.pcap.xlsx
at sun.nio.fs.UnixPath.encode(UnixPath.java:147)
at sun.nio.fs.UnixPath.(UnixPath.java:71)
at sun.nio.fs.UnixFileSystem.getPath(UnixFileSystem.java:281)
at sun.nio.fs.AbstractPath.resolve(AbstractPath.java:53)
at org.ttzero.excel.entity.IWorkbookWriter.reMarkPath(IWorkbookWriter.java:104)
at org.ttzero.excel.entity.e7.XMLWorkbookWriter.reMarkPath(XMLWorkbookWriter.java:436)
at org.ttzero.excel.entity.e7.XMLWorkbookWriter.writeTo(XMLWorkbookWriter.java:118)
at org.ttzero.excel.entity.Workbook.writeTo(Workbook.java:680)
打印看系统编码
file.encoding: UTF-8
LANG: zh_CN.UTF-8
LANGUAGE: zh_CN:en_US
LC_ALL: zh_CN.UTF-8

业务代码就是在writeTo报错:
Workbook wb = new Workbook(fileName); //fileNameb为 MO样例1.pcap.xlsx
//数据导出
wb.writeTo(Paths.get(comPath));
请问这是编码问题吗,要怎么改才能支持中文

@wangguanquan
Copy link
Owner

wangguanquan commented Oct 24, 2024

我在网上查了一下有挺多这种场景,出问题应该是Paths.get(comPath + "/MO样例1.pcap.xlsx")这一句,你可以尝试独立出这一句来执行并验证,我并没有这样的环境所以无法给出准确的解决办法,以下解决方法可以逐一尝试

  1. 避免使用Paths创建中文路程径,首先Workbook使用无参构造函数,其次将wb.writeTo(Paths.get(comPath));改为wb.writeTo(new File(comPath + "/" + fileName));
  2. 避免创建本地文件,将workbook直接写入输出流wb.writeTo(new FileOutputStream(comPath + "/" + fileName));

@zhangwx95
Copy link
Author

感谢大佬,可以确认就是文件名称带中文导致的,把中文替换掉是ok的,不过提供的两个方法仍然不能正确的显示中文文件名
方法1,报错和之前一样
方法2,报错java.io.FileNotFoundException:,将目录创建后
Path path = Paths.get(comPath);
if (!Files.exists(path)) {
Files.createDirectories(path);
}
文件生成成功,但是中文仍然没被识别,被替换成了下划线 MO__1.pcap.xlsx TAT

@wangguanquan
Copy link
Owner

wangguanquan commented Oct 24, 2024

方法2是HTTP下载后中文无法被识别吗?如果是这样的话可以设置Response头来解决,直接使用以下代码测试一下

@RequestMapping("/download")
public void download(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String fileName = java.net.URLEncoder.encode("MO样例1.pcap.xlsx", "UTF-8");
    response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"; filename*=utf-8''" + fileName);
    new Workbook().addSheet(new EmptySheet()).writeTo(response.getOutputStream());
}

@zhangwx95
Copy link
Author

方法2是这个意思吗,我理解错了;
我还是通过 wb.writeTo(new FileOutputStream(comPath + encodeFileName)); 生成文件
应该是我的docker镜像有问题,我再看看,谢谢大佬

@wangguanquan
Copy link
Owner

应该是最初的写法引起误解了,方法2直接写到输出流是为了规避将中文文件名写到本地上,所以直接写入response。你可以尝试一下上面的完整示例代码看一下是否能正常。

即便正常也会有一定问题,上面示例代码只支持同步下载,数据量大的话可能会造成前端页面假死,异步下载的话可以将文件名进行编码或者用ID代替,下载的时候使用这个编码或ID找到实际文件名,然后使用上面的方法直接下载即可。

@zhangwx95
Copy link
Author

谢谢大佬,你给的方法2确实下载没有问题,名称中文都正常

我最后重新在ubuntu22.04上做了个支持中文的镜像,然后启动docker出现了
There is insufficient memory for the Java Runtime Environment to continue.

Cannot create GC thread. Out of system resources.

折腾不出来,最后直接用了--privileged启动docker 就正常启动了,结果文件中文名称也正常

提问的那个版本的docker镜像应该是中文设置没生效导致的,但是也很奇怪只有文件名中文异常,文件里面的sheet名称 文件内容、系统里的log打印中文都正常。。。

不过总之就是docker镜像的问题,重新做一个就好了。。。谢谢大佬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants