首页 > 解决方案 > 将 Microsoft Teams 聊天导出到文件以进行归档

问题描述

有没有人设法以任何文件格式(包括聊天图像,例如屏幕截图、用户头像等)保存来自 Microsoft Teams 的整个聊天记录?

我已经在所有浏览器中以所有可以想到的方式进行了尝试。

问题似乎是 Teams 从内存中删除了当前视口中不包含的所有文本,甚至更多的是图像。

这看起来像延迟加载,但显然不是,因为无法通过禁用浏览器中的延迟加载选项来阻止它(在 Chrome 和 Firefox 中使用基于浏览器的 Teams 版本进行了尝试)。

仅显示和加载当前视口的内容。滚动时会立即卸载所有其他向上和向下的内容。因此,无法以任何方式分别选择、保存或导出整个聊天,甚至无法将其复制到剪贴板:

滚动时立即卸载视口外的内容

标签: lazy-loadingmicrosoft-teamsarchivingmicrosoft-exchange

解决方案


这是我在 Chrome 控制台中提出的一些意大利面条——它会滚动到您选择的任何聊天的顶部,然后逐条向下移动,创建一个可打印/可保存的副本。甚至加载所有内联图片。

唯一的问题是,很长的聊天记录需要一段时间才能滚动到开头。

所以,是的,要使用,只需打开Chrome 控制台窗口(Ctrl+Shift+J) 复制并粘贴它,然后按 Enter。然后等待它施展魔法。

let xxx = 0;
let ddd = 0;
let fullpage1 = '' 

fullpage1 = '<h1 id="chat-header-title2">'+jQuery('#chat-header-title').html()+'</h1>';

//**********************************************
//Go to top of page

jj234 = function() {


jQuery("virtual-repeat").scrollTop(-2000);



if (xxx < 50) {setTimeout(jj234, 50); } else {setTimeout(ScrollDownTakeNote, 1000); }

if (jQuery("virtual-repeat").hasClass("not-at-top")) {xxx = 0;} else {xxx += 1;} 

}

jj234();


//Create a place to hold a copy of the content
jQuery("body").append('<div id="thebigdiv" style="z-index: 10000; overflow: auto; background: white;"></div>');


//*************************************************
//Scroll down the chat, once things load, copy it to the temp location, removing some dynamic content

ScrollDownTakeNote = function() {

if (jQuery('.disable-event').length==0 && jQuery('.ts-image .loading').length==0) {
ddd += 1;

jQuery("#thebigdiv").append('<div id="boxdiv'+ddd+'"></div>');

jQuery("virtual-repeat div.clearfix").each( function () {
jQuery("#boxdiv"+ddd).append('<div class="messageClip" id="'+jQuery(this).attr('id')+'">' + jQuery(this).html() + '</div>');
});

jQuery("#boxdiv"+ddd+" [data-tid]").attr("data-tid","");

jQuery("#boxdiv"+ddd+" [ng-if]").attr("ng-if","");

jQuery("#boxdiv"+ddd+" [ng-class]").attr("ng-class","");

jQuery("#boxdiv"+ddd+" [ng-source]").attr("ng-source","");

jQuery("#boxdiv"+ddd+" [ng-class]").attr("ng-class","");

jQuery("#boxdiv"+ddd+" [simple-mouseenter]").attr("simple-mouseenter","");

jQuery("#boxdiv"+ddd+" [ng-mouseleave]").attr("ng-mouseleave","");

jQuery("#boxdiv"+ddd+" [message-view-model]").attr("message-view-model","");

jQuery("#boxdiv"+ddd+" [message-vm]").attr("message-vm","");

jQuery("#boxdiv"+ddd+" [is-enabled]").attr("is-enabled","");

jQuery("#boxdiv"+ddd+" [host-tenant-id]").attr("host-tenant-id","");


jQuery("#boxdiv"+ddd+" [scroll-item-tracker]").attr("scroll-item-tracker","");
jQuery("#boxdiv"+ddd+" [scroll-item-id]").attr("scroll-item-id","");
jQuery("#boxdiv"+ddd+" [scroll-item-event-name]").attr("scroll-item-event-name","");
jQuery("#boxdiv"+ddd+" [is-above-view-callback]").attr("is-above-view-callback","");
jQuery("#boxdiv"+ddd+" [is-in-view-callback]").attr("is-in-view-callback","");
jQuery("#boxdiv"+ddd+" [scroll-container]").attr("scroll-container","");
jQuery("#boxdiv"+ddd+" [check-above-viewport]").attr("check-above-viewport","");
jQuery("#boxdiv"+ddd+" [delay-scroll-tracker-init]").attr("delay-scroll-tracker-init","");
jQuery("#boxdiv"+ddd+" [deferred-render-ready]").attr("deferred-render-ready","");

jQuery("#boxdiv"+ddd+" img[target-src]").each(function () {$(this).attr("lazy-load","false"); $(this).attr("src",$(this).attr("target-src"));});

jQuery("#boxdiv"+ddd+" skype-status").remove();

fullpage1 += jQuery("#thebigdiv").html();
jQuery("#thebigdiv").html(".");

jQuery("virtual-repeat.simple-scrollbar").scrollTop(jQuery("virtual-repeat.simple-scrollbar").scrollTop()+2000);

}

if  (jQuery('[data-scroll-pos="1"').length==0 || jQuery("virtual-repeat").hasClass("not-at-bottom") || jQuery('.disable-event').length>0 || jQuery('.ts-image .loading').length>0 ) {setTimeout(ScrollDownTakeNote, 500);
} else {printdiv("#thebigdiv")}

};

//**********************************
//Open a Save File dialog for the HTML source and open the print window for a Print-to-PDF
//(Why not both?)

function printdiv(printdivname) {
        jQuery(printdivname).html(fullpage1);
    jQuery('#outer-shell').remove();
    jQuery('body').css({"overflow":"scroll"});
    
    $('div.messageClip[id]').each(function () {
            $('div.messageClip[id="' + this.id + '"]:gt(0)').remove();
    });
    jQuery(printdivname).css({"margin-left":"15px"});
    jQuery('body').append("<style>@media print { * { overflow: visible !important; } .page { page-break-after:always; }}");
    jQuery('head').append('<link rel="stylesheet" href="https://statics.teams.cdn.office.net/hashed/stylesheets.theme-defaultV2.min-86505e7.css" />');
    
    fullpage2 = new XMLSerializer().serializeToString(document);
    //fullpage2 = fullpage2.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
    //  return '&#'+i.charCodeAt(0)+';'; 
    //});

    saveTextAsFile(fullpage2);  

    waitonimages();
    
}

let xasd = 0;
function waitonimages() {
    xasd = 0;
    jQuery("img").each(function () {if (!this.complete) { xasd+=1 }});
    if (xasd == 0) {window.print()} else {setTimeout(waitonimages,1000);}   
}

function saveTextAsFile(text1)
{
    //inputTextToSave--> the text area from which the text to save is
    //taken from
    var textToSave = text1;
    var textToSaveAsBlob = new Blob([textToSave], {type:"text/html"});
    var textToSaveAsURL = window.URL.createObjectURL(textToSaveAsBlob);
    //inputFileNameToSaveAs-->The text field in which the user input for 
    //the desired file name is input into.
    var fileNameToSaveAs = jQuery('#chat-header-title2').html() + "-source.htm";

    var downloadLink = document.createElement("a");
    downloadLink.download = fileNameToSaveAs;
    downloadLink.innerHTML = "Download File";
    downloadLink.href = textToSaveAsURL;
    downloadLink.onclick = destroyClickedElement;
    downloadLink.style.display = "none";
    document.body.appendChild(downloadLink);

    downloadLink.click();
}

function destroyClickedElement(event)
{
    document.body.removeChild(event.target);
}

推荐阅读