Word 歸檔 在 Word 下整理聊天訊息的規範。 訊息在拷貝至 Word 時,已經携帶一定的格式。 該方法適用於未使用 QQNT 資料庫的 QQ 或 TIM 版本。
基本規範
WORD
WPS文字
中文 / 西文字體:等綫 字形:加粗 字號:五號 / 10.5 字體顔色: A: R 201 G 138 B 218(C98ADA) B: R 112 G 173 B 71(70AD47) 效果:All Off
中文 / 西文字體:等綫 字形:加粗 字號:五號 / 10.5 字體顔色: A: R 201 G 138 B 218(C98ADA) B: 112 G 173 B 71(70AD47) 效果:All Def
為何使用 WPS ? WPS 的大尺寸文件處理能力非常强大! 我在整理訊息的時候 Word 突然卡頓死亡,修復無果 : ( 頁面 500 ,字數 160K ,這在過去只需等待十秒鐘便可加載完成。 啊啊,果然每次整理聊天訊息的時候,都是系統要重灌的時候呢(笑)
方案:Word + Pdf
聊天訊息拷貝至 Word;
使用 VBA 宏將 IMG 統一縮放至 40%
;
Ctrl +C
全選内容,設置字號為五號;
匿稱替換,格式為^p匿稱
,如 ^pMagstic
;
^p
為換行
匿稱後的空格為  
該轉換為匹配 常規訊息
匿稱替換,格式為匿稱
,如 Magstic
;
^p
為換行
匿稱後的空格為  
該轉換為匹配 訊息引用
校對訊息的缺漏;
卡片訊息使用 Link 替代
有效 / 失效文件使用 截圖替代
失效 IMG 文件使用 Cache文件名追索並替換
縮放圖像以美化排版
未漫游的斷層訊息使用 QQMobile 的截圖
若以上訊息有缺失,則標注【LOST】
設定文檔分欄為 2 ;
轉換為 Pdf ,和 Word 共同存儲。
方案:Word + Markdown Word + Markdown 整理聊天訊息的規範。 結果上較為粗放,但提供了更高效的校對方式。 這亦是未來的個人備份聊天記錄的備選方案之一。
聊天訊息拷貝至 Word;
使用 VBA 宏將 IMG 統一縮放至 40%
;
Ctrl +C
全選内容,設置字號為五號;
匿稱替換,格式為^p匿稱
,如 ^pMagstic
;
匿稱替換,格式為匿稱
,如 Magstic
;
^p
為換行
匿稱後的空格為  
該轉換為匹配 訊息引用
校對卡片訊息和失效文件;
卡片訊息使用 Link替代
有效 / 失效文件使用 【文件】Name.zip(12.34MB)
替代
未漫游的斷層訊息使用 QQMobile 的截圖
若以上訊息有缺失,則標注【LOST】
使用 Pandoc 將 Doc 轉為 Markdown,並使用 PowerShell 清理 Markdown 的無用標記;
使用 RAR 額外存檔媒體文件 ,和 Word 共同存儲。
相關指令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Sub ImgSize() Dim imgHeight As Single Dim imgWidth As Single Dim iShape As InlineShape Dim n As Single n = 0.5 For Each iShape In ActiveDocument.InlineShapes iShape.LockAspectRatio = msoTrue imgHeight = iShape.Height imgWidth = iShape.Width iShape.Height = n * imgHeight iShape.Width = n * imgWidth Next iShape End Sub
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Sub ImgSizeBatch() Dim docPath As String Dim docName As String Dim doc As Document Dim imgHeight As Single Dim imgWidth As Single Dim iShape As InlineShape Dim n As Single n = 0.4 docPath = "E:\File\2024\" docName = Dir(docPath & "*.docx" ) Do While docName <> "" Set doc = Documents.Open(docPath & docName) For Each iShape In doc.InlineShapes iShape.LockAspectRatio = msoTrue imgHeight = iShape.Height imgWidth = iShape.Width iShape.Height = n * imgHeight iShape.Width = n * imgWidth Next iShape doc.SaveAs2 docPath & docName doc.Close docName = Dir() Loop End Sub
1 pandoc -s 2023.04 .docx -o 2023.04 .md --extract-media =2023.04 --wrap =none
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 $successCount = 0 $errorCount = 0 $errorFiles = @ ()Write-Host @" 本程式將執行以下操作: 1. 掃描當前目錄下所有 MD 檔案 2. 清理檔案中的寬高標記 3. 移除所有反斜線 4. 使用 UTF-8 BOM 編碼重新保存 是否繼續? (Y/N) "@ -ForegroundColor Yellow$response = Read-Host if ($response .ToUpper() -ne 'Y' ) { Write-Host "操作已取消" -ForegroundColor Red exit } $mdFiles = Get-ChildItem -Path $PSScriptRoot -Filter "*.md" Write-Host "開始處理文件..." -ForegroundColor Cyanforeach ($file in $mdFiles ) { try { Write-Host "正在處理:" $file .Name $content = Get-Content -Path $file .FullName -Raw -Encoding UTF8 $newContent = $content -replace '{width="[^"]*"\s*height="[^"]*"}' , '' $lines = $newContent -split "`r`n|`r|`n" $processedLines = $lines | ForEach-Object { $line = $_ $line = $line -replace '\\' , '' $line } $finalContent = $processedLines -join "`n" [System.IO.File ]::WriteAllText($file .FullName, $finalContent , [System.Text.Encoding ]::UTF8) $successCount ++ Write-Host "成功處理:" $file .Name -ForegroundColor Green } catch { $errorCount ++ $errorFiles += $file .Name Write-Host "處理失敗:" $file .Name -ForegroundColor Red Write-Host "錯誤信息:" $_ .Exception.Message -ForegroundColor Red } } Write-Host "`n處理完成!" -ForegroundColor YellowWrite-Host "成功處理文件數:$successCount " -ForegroundColor GreenWrite-Host "失敗文件數:$errorCount " -ForegroundColor Redif ($errorFiles .Count -gt 0 ) { Write-Host "`n失敗的文件列表:" -ForegroundColor Red $errorFiles | ForEach-Object { Write-Host "- $_ " -ForegroundColor Red } } Write-Host "`n按任意鍵退出..." -ForegroundColor Yellow$null = $Host .UI.RawUI.ReadKey("NoEcho,IncludeKeyDown" )
茶後小敘 個人一直在使用 TIM 3.4.8(22086) ,因此可以使用 Ctrl + A
全選消息管理器中的訊息。 在 QQNT 之後,這種方式已經無法使用。 現在個人使用的 TIM ,也已在 2025 年 無法離線漫游 聊天訊息。 我無法如 Geek 那般解密聊天資料庫,也無法時刻讓我的 PC 上的 TIM Online。 哈哈,更不必提舊版軟體時刻有被限制登入的風險。
不過幸運的是, QQNT 支援手動框選訊息,且可以拷貝! 這非常辛苦,不過爲了回憶留存,也無妨了。
現在有項目可以解密 QQNT 資料庫,但解碼歸檔始終無期。 多方權衡,我只能選擇這樣拙劣的方法。 順帶一提,文字替換其實也研究過 VBA 宏,只是無效……沒錯,那個  
空格。 啊,就這樣吧。 我想我還有 180K 條訊息要整理呢 : )
Markdown 歸檔 方案:Markdown 該方式適用於 QQNT ,亦是未來的備份聊天的至高備選。 QQNT 的資料庫足夠高效,以致於訊息斷層的可能性基本為零。 不足之處在於:每次至多手動框選 100 條訊息,且無法拷貝引用内容。
在 QQNT 中框選訊息;
使用 QQNT 的 “複製” 功能拷貝訊息;
在 VS Code 中粘貼訊息;
現在,訊息便可在 Obsidian 等 Markdown 編輯器中閲讀。 不過注意到了嗎?訊息中的 IMG 是絕對連結,這不利於歸檔。
使用 Ps1 指令將 HTML IMG 轉為 Markdown IMG,并設置相對連結;
若一直使用 QQNT 進行訊息收發,簡單校對 Files 便可結束。 若 QQNT 資料庫使用舊版資料庫轉化而來,則需校對無法正確引用的 IMG。
檢索 “暂不支持的消息类型” ,校對。
使用 RAR 存檔文件 ,且進行多重備份。
相關指令 簡易版,適用於純 QQNT。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 $scriptPath = $PSScriptRoot $mdFiles = Get-ChildItem -Path $scriptPath -Filter "*.md" function Convert-MDImages { param ( [Parameter (Mandatory =$true )] [string ]$MDFilePath ) try { if (-not (Test-Path $MDFilePath )) { throw "檔案不存在: $MDFilePath " } $mdFileName = [System.IO.Path ]::GetFileNameWithoutExtension($MDFilePath ) $mdDirectory = Split-Path $MDFilePath -Parent $mediaPath = Join-Path $mdDirectory "$mdFileName \media" New-Item -ItemType Directory -Force -Path $mediaPath | Out-Null $content = Get-Content $MDFilePath -Raw -Encoding UTF8 $pattern = '<img\s+src="file:\/\/([^"]+)"\s*\/>' $newContent = [regex ]::Replace($content , $pattern , { param ($match ) $originalPath = $match .Groups[1 ].Value $fileName = [System.IO.Path ]::GetFileName($originalPath ) $newImagePath = Join-Path $mediaPath $fileName if (Test-Path $originalPath ) { Copy-Item $originalPath $newImagePath -Force return "![image](./$mdFileName /media/$fileName )" } Write-Warning "找不到圖片: $originalPath " return $match .Value }) $newContent | Out-File $MDFilePath -Encoding UTF8 -Force Write-Host "處理完成!檔案 $MDFilePath 的圖片已移動至: $mediaPath " -ForegroundColor Green } catch { Write-Error "錯誤: $_ " } } foreach ($file in $mdFiles ) { Write-Host "正在處理檔案: $ ($file .FullName)" -ForegroundColor Yellow Convert-MDImages -MDFilePath $file .FullName }
複雜版,適用於非 QQNT。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 $scriptPath = $PSScriptRoot $mdFiles = Get-ChildItem -Path $scriptPath -Filter "*.md" function Convert-MDImages { param ( [Parameter (Mandatory =$true )] [string ]$MDFilePath ) try { if (-not (Test-Path $MDFilePath )) { throw "檔案不存在: $MDFilePath " } $mdFileName = [System.IO.Path ]::GetFileNameWithoutExtension($MDFilePath ) $mdDirectory = Split-Path $MDFilePath -Parent $mediaPath = Join-Path $mdDirectory "$mdFileName \media" New-Item -ItemType Directory -Force -Path $mediaPath | Out-Null $content = Get-Content $MDFilePath -Raw -Encoding UTF8 $pattern = '<img\s+src="file:\/\/([^"]+)"\s*\/?>' $newContent = $content [regex ]::Matches($content , $pattern ) | ForEach-Object { $match = $_ $originalPath = $match .Groups[1 ].Value $escapedPath = [Management.Automation.WildcardPattern ]::Escape($originalPath ) $fileName = [System.IO.Path ]::GetFileName($originalPath ) $safeFileName = [System.IO.Path ]::GetFileNameWithoutExtension($fileName ) + [System.IO.Path ]::GetExtension($fileName ) $newImagePath = Join-Path $mediaPath $safeFileName if (Test-Path $escapedPath ) { Copy-Item $escapedPath $newImagePath -Force $replacement = "![image](./$mdFileName /media/$safeFileName )" $newContent = $newContent .Replace($match .Value, $replacement ) } else { Write-Warning "圖像尋找失敗: $originalPath " } } $newContent | Out-File $MDFilePath -Encoding UTF8 -Force Write-Host "MD 中的 HTMLIMG 已處理完畢!檔案 $MDFilePath 的 IMG 已移動至: $mediaPath " -ForegroundColor Green } catch { Write-Error "ERROR: $_ " } } foreach ($file in $mdFiles ) { Write-Host "正在處理檔案: $ ($file .FullName)" -ForegroundColor Yellow Convert-MDImages -MDFilePath $file .FullName }
茶後小敘 這時,我已歸檔了全部訊息,可以正式開始資料備份。 在歸檔過程中,我遭遇無數阻力,這是程式碼無法解析的,只能人力精校。
現在一切都結束了嗎?或許不是的。 表情貼圖的大小不一,造成 Markdown 的閲讀體驗不會很好。
現在粗略的解決方案是建立一個貼圖庫,透過 MD5 校驗來定位表情貼圖。 最後使用批處理的手段將貼圖縮放,而後批量替換 Markdown 中的貼圖路徑。
非常笨拙的手段,呵呵。不過也別無他法。 圖像識別手段現在尚且羸弱,無法支持我的需求。
好了,就這樣,下次見: ) 我會帶著嶄新的作業系統來寫 Blog XD