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

如何解决Android WebView下载网页Excel文件为空的问题

问题根因

WebView下载得到空Excel文件,和以下几个常见实现缺陷直接相关:

  • 站点Excel导出接口存在请求校验,现有代码仅传递Cookie和UA,缺少Referer等必填头,或接口要求POST请求但DownloadManager默认发GET请求,服务端返回空响应/错误跳转页,保存为.xlsx后缀后自然显示为空
  • 存储配置未适配Android 10+分区存储规则,旧版WRITE_EXTERNAL_STORAGE权限在高版本失效,路径写入异常生成空文件
  • 硬编码回调返回的mimeType,当服务端返回的响应头mimeType和实际文件不匹配时,会触发DownloadManager请求拦截,拿到空内容
修复步骤

1. 修正清单文件配置

替换原有存储权限配置,适配全版本Android系统:

<!-- Android 13+ 通知权限,用于显示下载进度 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- Android 13+ 媒体文件读取权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- Android 9及以下版本存储写入权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="28" />

<application
    ...
    android:requestLegacyExternalStorage="true"
    ...>

2. 替换下载监听逻辑

补全必要请求头,移除错误的mimeType硬编码,适配高版本存储规则:

// 权限申请逻辑同步调整:Android 13+申请POST_NOTIFICATIONS,Android 9及以下才申请WRITE_EXTERNAL_STORAGE
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_DENIED) {
        requestPermissions(new String[]{Manifest.permission.POST_NOTIFICATIONS}, 1);
    }
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
    if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
        requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
    }
}

// 下载监听逻辑
web_view.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -> {
    String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType);
    String cookies = CookieManager.getInstance().getCookie(url);

    DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
    // 移除原有的setMimeType调用,让DownloadManager自动从响应头识别文件类型,避免拦截
    // 补全Referer请求头,绝大多数站点会校验该字段防止非法跨域请求
    request.addRequestHeader("cookie", cookies);
    request.addRequestHeader("User-Agent", userAgent);
    request.addRequestHeader("Referer", web_view.getUrl());
    request.setDescription("下载中");
    request.setTitle(fileName);
    request.allowScanningByMediaScanner();
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setAllowedOverMetered(true);
    request.setAllowedOverRoaming(true);
    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);

    DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
    dm.enqueue(request);
    Toast.makeText(getApplicationContext(), "文件已开始下载,可在通知栏查看进度,完成后在系统下载目录查找", Toast.LENGTH_LONG).show();
});

3. POST导出场景特殊处理

如果页面Excel导出是通过表单POST提交触发的,DownloadManager默认发GET请求无法拿到内容,需要在WebView初始化时开启以下配置,让WebView自动处理POST类下载请求:

web_view.getSettings().setJavaScriptEnabled(true);
web_view.getSettings().setDomStorageEnabled(true);
web_view.getSettings().setAllowFileAccess(true);
CookieManager.getInstance().setAcceptThirdPartyCookies(web_view, true);
排查技巧
  • 若下载得到的文件大小仅几KB,可将后缀改为.txt打开查看内容,大概率是服务端返回的鉴权失败、参数错误提示页,说明请求头或请求方法不匹配
  • 对比Chrome浏览器触发下载时的请求方法、请求头参数,和WebView发出的请求对齐即可解决90%以上的空文件问题
  • Android 10及以上版本不要申请WRITE_EXTERNAL_STORAGE权限,该权限在高版本已失效,强制申请反而会导致存储访问异常

内容的提问来源于stack exchange,提问作者Computer knowledge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 20:03:39