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

Xamarin Android:WebView加载内部存储CSV文件失败的解决方法

问题描述

我正在开发Xamarin Android项目,已将下载的CSV文件存储至内部存储,文件路径为:/storage/emulated/0/Android/data/com.abc.def/files/ABC/MyListSample.csv。我希望将该CSV文件加载到WebView中,尝试了以下两段代码但均未能成功加载,且不想使用Open CSV等第三方库,现寻求解决方案。

尝试的代码

第一段代码

_webview = (WebView)FindViewById(Resource.Id.webView);

_webview.SetInitialScale (0);
_webview.Settings.JavaScriptEnabled = true;
_webview.Settings.SetSupportMultipleWindows (false);
_webview.Settings.AllowFileAccess = true;
_webview.Settings.SetPluginState (WebSettings.PluginState.On);//Try
_webview.Settings.BuiltInZoomControls = false;
_webview.Settings.JavaScriptCanOpenWindowsAutomatically = true;

_webview.Settings.AllowUniversalAccessFromFileURLs = true;

_webview.LoadUrl(string.Format("file://" + filepath));

第二段代码

Java.IO.File csv = new Java.IO.File(filepath);

_webview.LoadUrl(string.Format("file://" + csv));
解决方案

WebView本身不支持直接渲染CSV文件,以下是两种无需第三方库的原生实现方案:

方法1:将CSV转换为HTML表格后加载

读取CSV内容并手动解析为HTML表格结构,再通过WebView加载:

// 读取CSV文件内容
string csvContent = File.ReadAllText(filepath);
// 分割行并过滤空行
string[] rows = csvContent.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

// 构建HTML表格
StringBuilder htmlBuilder = new StringBuilder();
htmlBuilder.Append("<html><body><table border='1' style='border-collapse:collapse;'>");

foreach (string row in rows)
{
    htmlBuilder.Append("<tr>");
    // 处理带引号的列(忽略引号内的逗号)
    var columns = row.Split(',')
                     .Select(col => col.Trim('"'))
                     .ToList();
    foreach (string col in columns)
    {
        htmlBuilder.Append($"<td>{col}</td>");
    }
    htmlBuilder.Append("</tr>");
}

htmlBuilder.Append("</table></body></html>");

// 加载HTML到WebView
_webview.LoadDataWithBaseURL(null, htmlBuilder.ToString(), "text/html", "UTF-8", null);

注:如果CSV存在带逗号的引号包裹列(如"Smith, Alice"),可优化分割逻辑:遍历字符,跳过引号内的逗号。

方法2:用本地HTML模板+JS渲染CSV

  1. 在项目Assets目录创建csv_viewer.html文件:
<!DOCTYPE html>
<html>
<head>
    <style>
        table { border-collapse: collapse; width: 100%; }
        td, th { border: 1px solid #ddd; padding: 8px; }
        tr:nth-child(even) { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <table id="csvTable"></table>
    <script>
        function renderCsv(csvText) {
            const table = document.getElementById('csvTable');
            const rows = csvText.split('\n').filter(line => line.trim() !== '');
            
            rows.forEach(line => {
                const tr = document.createElement('tr');
                // 正则匹配带引号的列或普通列
                const cols = line.match(/(".*?"|[^",]+)(?=\s*,|\s*$)/g) || [];
                cols.forEach(col => {
                    const td = document.createElement('td');
                    td.textContent = col.replace(/^"|"$/g, '');
                    tr.appendChild(td);
                });
                table.appendChild(tr);
            });
        }
    </script>
</body>
</html>
  1. 在Xamarin代码中加载模板并注入CSV内容:
// 读取Assets中的HTML模板
string htmlTemplate;
using (StreamReader reader = new StreamReader(Assets.Open("csv_viewer.html")))
{
    htmlTemplate = reader.ReadToEnd();
}

// 读取CSV内容并转义JS特殊字符
string csvContent = File.ReadAllText(filepath);
string escapedCsv = csvContent.Replace("'", "\\'").Replace("\n", "\\n").Replace("\r", "");

// 拼接JS调用代码
string finalHtml = htmlTemplate.Replace("</body>", $"<script>renderCsv('{escapedCsv}');</script></body>");

// 加载到WebView
_webview.LoadDataWithBaseURL("file:///android_asset/", finalHtml, "text/html", "UTF-8", null);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:33:28