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

如何为DataGrid单元格设置InnerHtml并保留文本框解决Chrome打印空白问题?

解决Chrome打印时DataGrid文本框不显示的问题

这个问题本质是Chrome的默认打印样式对表单控件(比如<input>)的渲染逻辑导致的——默认情况下,Chrome可能会隐藏表单元素或者给它们加上不符合预期的样式,使得打印时看起来空白;而纯文本则能被正常渲染。下面给你几个可行的解决方案,按实现复杂度从低到高排序:

方案1:添加打印专用CSS(最推荐)

只需要在页面的样式中添加打印媒体查询,让文本框在打印时显示为纯文本样式,既保留编辑功能,又能正常打印内容:

@media print {
    /* 针对DataGrid里的文本框调整打印样式 */
    input[type="text"] {
        border: none;          /* 去掉边框 */
        background: transparent; /* 去掉背景 */
        -webkit-appearance: none; /* 移除Chrome默认的表单控件样式 */
        appearance: none;
        width: auto;           /* 让宽度适配内容 */
        vertical-align: middle; /* 和单元格内容对齐 */
        color: inherit;        /* 继承文本颜色 */
        font: inherit;         /* 继承字体样式 */
    }
}

这个方案不需要修改后台代码,只加一段CSS就能解决问题,打印时文本框会以纯文本的样式显示内容,同时页面上仍然是可编辑的文本框。

方案2:双内容模式(屏幕显示文本框,打印显示纯文本)

如果方案1不生效,可以给单元格同时添加可编辑的文本框和用于打印的隐藏文本,通过CSS控制不同场景下的显示:

第一步:修改后台代码,生成双内容结构

把你原来的c.Text赋值代码改成这样(用字符串插值让代码更清晰):

var id = ((DataRowView)e.Item.DataItem).Row["ID"].ToString();
var buyValue = ((DataRowView)e.Item.DataItem).Row["Buy0_45"].ToString();

// 同时添加打印用的隐藏span和可编辑的input
c.Text = $"<span class=\"print-content\">{buyValue}</span>" +
         $"<input id=\"txtBuy0-45{id}\" style=\"width:50px\" type=\"text\" value=\"{buyValue}\" onblur=\"UpdateBuyRate('0',{id},this.value)\" />";

第二步:添加控制显示的CSS

/* 屏幕上隐藏打印内容,显示文本框 */
.print-content {
    display: none;
}

/* 打印时隐藏文本框,显示纯文本 */
@media print {
    .print-content {
        display: inline;
    }
    input[type="text"] {
        display: none;
    }
}

第三步:同步编辑后的内容到打印文本

因为用户编辑文本框后,打印内容需要同步更新,所以修改你的UpdateBuyRate函数:

function UpdateBuyRate(param1, id, value) {
    // 原来的更新逻辑(比如提交到后台)
    // ...
    
    // 同步更新打印用的span内容
    const printSpan = document.querySelector(`#txtBuy0-45${id}`).previousElementSibling;
    if (printSpan) {
        printSpan.textContent = value;
    }
}

方案3:打印前后临时替换内容

通过监听浏览器的打印事件,在打印前把文本框替换成纯文本,打印完成后再恢复文本框:

第一步:后台代码给单元格添加标记

修改后台代码,给包含文本框的单元格添加自定义属性,方便后续JS识别和恢复:

var id = ((DataRowView)e.Item.DataItem).Row["ID"].ToString();
var buyValue = ((DataRowView)e.Item.DataItem).Row["Buy0_45"].ToString();
var inputHtml = $"<input id=\"txtBuy0-45{id}\" style=\"width:50px\" type=\"text\" value=\"{buyValue}\" onblur=\"UpdateBuyRate('0',{id},this.value)\" />";

c.Text = inputHtml;
// 添加标记,说明这个单元格有文本框
c.Attributes["data-is-editable-cell"] = "true";
// 保存原始的input HTML,用于恢复
c.Attributes["data-original-html"] = inputHtml;

第二步:添加打印事件监听的JS

// 打印前替换文本框为纯文本
window.addEventListener('beforeprint', function() {
    document.querySelectorAll('td[data-is-editable-cell="true"]').forEach(cell => {
        const input = cell.querySelector('input');
        if (input) {
            // 保存当前输入的值
            cell.dataset.currentValue = input.value;
            // 替换为纯文本
            cell.textContent = input.value;
        }
    });
});

// 打印后恢复文本框
window.addEventListener('afterprint', function() {
    document.querySelectorAll('td[data-is-editable-cell="true"]').forEach(cell => {
        const originalHtml = cell.dataset.originalHtml;
        const currentValue = cell.dataset.currentValue;
        // 恢复原始HTML
        cell.innerHTML = originalHtml;
        // 把当前值回填到文本框
        const input = cell.querySelector('input');
        if (input && currentValue) {
            input.value = currentValue;
        }
    });
});

以上三个方案中,方案1最简洁高效,建议优先尝试;如果因为特殊样式需求方案1不适用,再考虑方案2或3。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:56:45