Last active
September 9, 2025 16:52
-
-
Save eugrus/8e80bff589ba8bb03990cc113f41513b to your computer and use it in GitHub Desktop.
Copying Word styles between documents
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #Requires -Version 5.1 | |
| <# | |
| .SYNOPSIS | |
| Копирует все стили из одного документа Word в другой. | |
| .DESCRIPTION | |
| Этот скрипт открывает два документа Word: документ-донор и целевой документ. | |
| Затем он копирует все стили из донора в целевой документ, перезаписывая существующие стили с теми же именами. | |
| Для работы скрипта требуется, чтобы на компьютере был установлен Microsoft Word. | |
| .PARAMETER SourcePath | |
| Обязательный. Укажите путь к документу Word, из которого нужно скопировать стили (донор). | |
| .PARAMETER TargetPath | |
| Обязательный. Укажите путь к документу Word, в который нужно скопировать стили (целевой). | |
| .EXAMPLE | |
| .\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Donor.docx" -TargetPath "C:\Docs\Target.docx" | |
| Эта команда скопирует все стили из файла "Donor.docx" в файл "Target.docx". | |
| .NOTES | |
| Автор: Gemini | |
| Версия: 1.0 | |
| #> | |
| param( | |
| [Parameter(Mandatory=$true, HelpMessage="Путь к документу-донору (.docx)")] | |
| [string]$SourcePath, | |
| [Parameter(Mandatory=$true, HelpMessage="Путь к целевому документу (.docx)")] | |
| [string]$TargetPath | |
| ) | |
| # Проверка существования файлов | |
| if (-not (Test-Path -Path $SourcePath -PathType Leaf)) { | |
| Write-Error "Файл-донор не найден по указанному пути: $SourcePath" | |
| Exit 1 | |
| } | |
| if (-not (Test-Path -Path $TargetPath -PathType Leaf)) { | |
| Write-Error "Целевой файл не найден по указанному пути: $TargetPath" | |
| Exit 1 | |
| } | |
| # Попытка создать COM-объект Word.Application | |
| try { | |
| $wordApp = New-Object -ComObject Word.Application -ErrorAction Stop | |
| } | |
| catch { | |
| Write-Error "Не удалось запустить Microsoft Word. Убедитесь, что он установлен на этом компьютере." | |
| Exit 1 | |
| } | |
| # Сделаем Word невидимым для пользователя | |
| $wordApp.Visible = $false | |
| Write-Host "Открытие документов..." | |
| # Открытие документов | |
| try { | |
| # Получение полных путей к файлам | |
| $sourceDocPath = (Resolve-Path -Path $SourcePath).Path | |
| $targetDocPath = (Resolve-Path -Path $TargetPath).Path | |
| $sourceDoc = $wordApp.Documents.Open($sourceDocPath, $false, $true) # Open ReadOnly | |
| $targetDoc = $wordApp.Documents.Open($targetDocPath) | |
| } | |
| catch { | |
| Write-Error "Произошла ошибка при открытии документов. Убедитесь, что пути верны и файлы не повреждены." | |
| # Закрытие Word в случае ошибки | |
| $wordApp.Quit([ref]$false) # Не сохранять изменения | |
| [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wordApp) | Out-Null | |
| Exit 1 | |
| } | |
| Write-Host "Копирование стилей из '$($sourceDoc.Name)' в '$($targetDoc.Name)'..." | |
| try { | |
| # Основная операция: копирование стилей | |
| # Метод CopyStylesFromTemplate() принимает путь к шаблону или документу. | |
| $targetDoc.CopyStylesFromTemplate($sourceDoc.FullName) | |
| Write-Host "Стили успешно скопированы." -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Error "Не удалось скопировать стили. Ошибка: $($_.Exception.Message)" | |
| } | |
| finally { | |
| # Закрытие документов и приложения Word | |
| Write-Host "Закрытие документов и выход из Word..." | |
| # Сохранение и закрытие целевого документа | |
| $targetDoc.Close($true) # Сохранить изменения | |
| # Закрытие документа-донора без сохранения | |
| $sourceDoc.Close($false) | |
| # Завершение процесса Word | |
| $wordApp.Quit() | |
| # Освобождение COM-объектов из памяти | |
| [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sourceDoc) | Out-Null | |
| [System.Runtime.Interopservices.Marshal]::ReleaseComObject($targetDoc) | Out-Null | |
| [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wordApp) | Out-Null | |
| } | |
| Write-Host "Операция завершена." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #Requires -Version 5.1 | |
| <# | |
| .SYNOPSIS | |
| Копирует определенный стиль из одного документа Word в другой. | |
| .DESCRIPTION | |
| Этот скрипт открывает два документа Word: документ-донор и целевой документ. | |
| Затем он копирует один указанный стиль из донора в целевой документ, перезаписывая существующий стиль с тем же именем. | |
| Для работы скрипта требуется, чтобы на компьютере был установлен Microsoft Word. | |
| .PARAMETER SourcePath | |
| Обязательный. Укажите путь к документу Word, из которого нужно скопировать стиль (донор). | |
| .PARAMETER TargetPath | |
| Обязательный. Укажите путь к документу Word, в который нужно скопировать стиль (целевой). | |
| .PARAMETER StyleName | |
| Обязательный. Имя стиля, который нужно скопировать. | |
| .EXAMPLE | |
| .\Copy-SingleWordStyle.ps1 -SourcePath "C:\Docs\Donor.docx" -TargetPath "C:\Docs\Target.docx" -StyleName "Заголовок 1" | |
| .NOTES | |
| Автор: Modified script | |
| Версия: 3.0 | |
| #> | |
| param( | |
| [Parameter(Mandatory=$true, HelpMessage="Путь к документу-донору (.docx)")] | |
| [string]$SourcePath, | |
| [Parameter(Mandatory=$true, HelpMessage="Путь к целевому документу (.docx)")] | |
| [string]$TargetPath, | |
| [Parameter(Mandatory=$true, HelpMessage="Имя стиля для копирования")] | |
| [string]$StyleName | |
| ) | |
| function Release-ComObject([ref]$comObject) { | |
| if ($comObject.Value) { | |
| try { [System.Runtime.Interopservices.Marshal]::ReleaseComObject($comObject.Value) | Out-Null } catch {} | |
| $comObject.Value = $null | |
| } | |
| } | |
| # Проверка существования файлов | |
| if (-not (Test-Path -Path $SourcePath -PathType Leaf)) { | |
| Write-Error "Файл-донор не найден по указанному пути: $SourcePath" | |
| Exit 1 | |
| } | |
| if (-not (Test-Path -Path $TargetPath -PathType Leaf)) { | |
| Write-Error "Целевой файл не найден по указанному пути: $TargetPath" | |
| Exit 1 | |
| } | |
| # Попытка создать COM-объект Word.Application | |
| try { | |
| $wordApp = New-Object -ComObject Word.Application -ErrorAction Stop | |
| } | |
| catch { | |
| Write-Error "Не удалось запустить Microsoft Word. Убедитесь, что он установлен на этом компьютере." | |
| Exit 1 | |
| } | |
| $wordApp.Visible = $false | |
| $sourceDoc = $null | |
| $targetDoc = $null | |
| $tempDoc = $null | |
| $tempPath = $null | |
| try { | |
| # Открытие документов | |
| $sourceDoc = $wordApp.Documents.Open((Resolve-Path $SourcePath).Path, $false, $true) # ReadOnly | |
| $targetDoc = $wordApp.Documents.Open((Resolve-Path $TargetPath).Path) | |
| # Проверка существования стиля в исходном документе | |
| $sourceStyle = $null | |
| foreach ($style in $sourceDoc.Styles) { | |
| if ($style.NameLocal -eq $StyleName) { | |
| $sourceStyle = $style | |
| break | |
| } | |
| } | |
| if (-not $sourceStyle) { | |
| throw "Стиль '$StyleName' не найден в документе-доноре." | |
| } | |
| Write-Host "Копирование стиля '$StyleName' из '$($sourceDoc.Name)' в '$($targetDoc.Name)'..." | |
| # Создаем временный документ для копирования одного стиля | |
| $tempDoc = $wordApp.Documents.Add() | |
| $tempPath = "$env:TEMP\temp_style_copy_$(Get-Date -Format 'yyyyMMdd_HHmmss').docx" | |
| $sourceDoc.SaveAs2($tempPath) | |
| $tempDoc.Close($false) | |
| Release-ComObject ([ref]$tempDoc) | |
| # Открываем временную копию | |
| $tempDoc = $wordApp.Documents.Open($tempPath) | |
| # Удаляем все стили, кроме нужного | |
| foreach ($style in $tempDoc.Styles) { | |
| if ($style.NameLocal -ne $StyleName) { | |
| try { $style.Delete() } catch {} | |
| } | |
| } | |
| $tempDoc.Save() | |
| $targetDoc.CopyStylesFromTemplate($tempDoc.FullName) | |
| Write-Host "Стиль '$StyleName' успешно скопирован." -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Error "Ошибка: $($_.Exception.Message)" | |
| } | |
| finally { | |
| Write-Host "Закрытие документов и выход из Word..." | |
| # Закрытие временного документа | |
| if ($tempDoc) { | |
| try { $tempDoc.Close($false) } catch {} | |
| Release-ComObject ([ref]$tempDoc) | |
| } | |
| # Закрытие целевого документа (с сохранением) | |
| if ($targetDoc) { | |
| try { $targetDoc.Close($true) } catch {} | |
| Release-ComObject ([ref]$targetDoc) | |
| } | |
| # Закрытие документа-донора | |
| if ($sourceDoc) { | |
| try { $sourceDoc.Close($false) } catch {} | |
| Release-ComObject ([ref]$sourceDoc) | |
| } | |
| # Завершение процесса Word | |
| if ($wordApp) { | |
| try { $wordApp.Quit() } catch {} | |
| Release-ComObject ([ref]$wordApp) | |
| } | |
| # Удаление временного файла | |
| if ($tempPath -and (Test-Path $tempPath)) { | |
| Remove-Item $tempPath -ErrorAction SilentlyContinue | |
| } | |
| } | |
| Write-Host "Операция завершена." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #Requires -Version 5.1 | |
| <# | |
| .SYNOPSIS | |
| Копирует один или несколько стилей из одного документа Word в другой. | |
| .DESCRIPTION | |
| Этот скрипт открывает два документа Word: документ-донор и целевой документ. | |
| Затем он копирует указанные стили из донора в целевой документ, перезаписывая существующие стили с теми же именами. | |
| .PARAMETER SourcePath | |
| Путь к документу Word, из которого нужно скопировать стили (донор). | |
| .PARAMETER TargetPath | |
| Путь к документу Word, в который нужно скопировать стили (целевой). | |
| .PARAMETER StyleNames | |
| Массив имен стилей, которые нужно скопировать. | |
| .EXAMPLE | |
| .\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Donor.docx" -TargetPath "C:\Docs\Target.docx" -StyleNames "Заголовок 1","Обычный" | |
| .NOTES | |
| Автор: Modified script | |
| Версия: 4.1 | |
| #> | |
| param( | |
| [Parameter(Mandatory=$true, HelpMessage="Путь к документу-донору (.docx)")] | |
| [string]$SourcePath, | |
| [Parameter(Mandatory=$true, HelpMessage="Путь к целевому документу (.docx)")] | |
| [string]$TargetPath, | |
| [Parameter(Mandatory=$true, HelpMessage="Список стилей для копирования")] | |
| [string[]]$StyleNames | |
| ) | |
| function Release-ComObject([ref]$comObject) { | |
| if ($comObject.Value) { | |
| try { [System.Runtime.Interopservices.Marshal]::ReleaseComObject($comObject.Value) | Out-Null } catch {} | |
| $comObject.Value = $null | |
| } | |
| } | |
| # Проверка файлов | |
| foreach ($file in @($SourcePath, $TargetPath)) { | |
| if (-not (Test-Path -Path $file -PathType Leaf)) { | |
| Write-Error "Файл не найден: $file" | |
| Exit 1 | |
| } | |
| } | |
| # Создание COM-объекта Word | |
| try { | |
| $wordApp = New-Object -ComObject Word.Application -ErrorAction Stop | |
| } catch { | |
| Write-Error "Не удалось запустить Microsoft Word." | |
| Exit 1 | |
| } | |
| $wordApp.Visible = $false | |
| $sourceDoc = $null | |
| $targetDoc = $null | |
| $tempDoc = $null | |
| $tempPath = $null | |
| try { | |
| # Открытие документов | |
| $sourceDoc = $wordApp.Documents.Open((Resolve-Path $SourcePath).Path, $false, $true) # ReadOnly | |
| $targetDoc = $wordApp.Documents.Open((Resolve-Path $TargetPath).Path) | |
| # Проверка существования всех указанных стилей | |
| $missingStyles = @() | |
| foreach ($styleName in $StyleNames) { | |
| if (-not ($sourceDoc.Styles | Where-Object { $_.NameLocal -eq $styleName })) { | |
| $missingStyles += $styleName | |
| } | |
| } | |
| if ($missingStyles.Count -gt 0) { | |
| throw "Следующие стили не найдены в документе-доноре: $($missingStyles -join ', ')" | |
| } | |
| Write-Host "Копирование стилей: $($StyleNames -join ', ')" | |
| # Создаем временный документ | |
| $tempDoc = $wordApp.Documents.Add() | |
| $tempPath = "$env:TEMP\temp_style_copy_$(Get-Date -Format 'yyyyMMdd_HHmmss').docx" | |
| $sourceDoc.SaveAs2($tempPath) | |
| $tempDoc.Close($false) | |
| Release-ComObject ([ref]$tempDoc) | |
| # Открываем временный документ (с параметрами для скрытого открытия) | |
| $tempDoc = $wordApp.Documents.Open($tempPath, $false, $false, $false) | |
| # Убеждаемся, что окно временного документа скрыто | |
| $tempDoc.ActiveWindow.Visible = $false | |
| # Удаляем все стили, кроме нужных | |
| foreach ($style in $tempDoc.Styles) { | |
| if ($StyleNames -notcontains $style.NameLocal) { | |
| try { $style.Delete() } catch {} | |
| } | |
| } | |
| $tempDoc.Save() | |
| # Копирование стилей в целевой документ | |
| $targetDoc.CopyStylesFromTemplate($tempDoc.FullName) | |
| Write-Host "Стили успешно скопированы." -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Error "Ошибка: $($_.Exception.Message)" | |
| } | |
| finally { | |
| Write-Host "Закрытие документов и выход из Word..." | |
| # Закрытие временного документа | |
| if ($tempDoc) { | |
| try { $tempDoc.Close($false) } catch {} | |
| Release-ComObject ([ref]$tempDoc) | |
| } | |
| # Закрытие целевого документа с сохранением | |
| if ($targetDoc) { | |
| try { $targetDoc.Close($true) } catch {} | |
| Release-ComObject ([ref]$targetDoc) | |
| } | |
| # Закрытие документа-донор без сохранения | |
| if ($sourceDoc) { | |
| try { $sourceDoc.Close($false) } catch {} | |
| Release-ComObject ([ref]$sourceDoc) | |
| } | |
| # Завершение Word | |
| if ($wordApp) { | |
| try { $wordApp.Quit() } catch {} | |
| Release-ComObject ([ref]$wordApp) | |
| } | |
| # Удаление временного файла | |
| if ($tempPath -and (Test-Path $tempPath)) { | |
| Remove-Item $tempPath -ErrorAction SilentlyContinue | |
| } | |
| } | |
| Write-Host "Операция завершена." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #Requires -Version 5.1 | |
| <# | |
| .SYNOPSIS | |
| Копирует один или несколько стилей из одного документа Word в другой. | |
| .DESCRIPTION | |
| Этот скрипт открывает два документа Word: документ-донор и целевой документ. | |
| Затем он копирует указанные стили из донора в целевой документ, перезаписывая существующие стили с теми же именами. | |
| Поддерживает форматы .docx, .dotm и .rtf. | |
| .PARAMETER SourcePath | |
| Путь к документу Word, из которого нужно скопировать стили (донор). | |
| .PARAMETER TargetPath | |
| Путь к документу Word, в который нужно скопировать стили (целевой). | |
| .PARAMETER StyleNames | |
| Массив имен стилей, которые нужно скопировать. | |
| .PARAMETER Verbose | |
| Включает подробный вывод диагностической информации. | |
| .EXAMPLE | |
| .\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Donor.docx" -TargetPath "C:\Docs\Target.docx" -StyleNames "Заголовок 1","Обычный" | |
| .EXAMPLE | |
| .\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Template.dotm" -TargetPath "C:\Docs\Target.docx" -StyleNames "MyStyle" -Verbose | |
| .EXAMPLE | |
| .\Copy-WordStyles.ps1 -SourcePath "C:\Docs\Source.rtf" -TargetPath "C:\Docs\Target.rtf" -StyleNames "Citation" | |
| .NOTES | |
| Автор: Modified script | |
| Версия: 4.4 | |
| #> | |
| [CmdletBinding()] | |
| param( | |
| [Parameter(Mandatory=$true, HelpMessage="Путь к документу-донору (.docx/.dotm/.rtf)")] | |
| [string]$SourcePath, | |
| [Parameter(Mandatory=$true, HelpMessage="Путь к целевому документу (.docx/.dotm/.rtf)")] | |
| [string]$TargetPath, | |
| [Parameter(Mandatory=$true, HelpMessage="Список стилей для копирования")] | |
| [string[]]$StyleNames | |
| ) | |
| function Release-ComObject([ref]$comObject) { | |
| if ($comObject.Value) { | |
| try { | |
| $released = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($comObject.Value) | |
| Write-Verbose "COM-объект освобожден (refcount: $released)" | |
| } catch { | |
| Write-Verbose "Ошибка при освобождении COM-объекта: $_" | |
| } | |
| $comObject.Value = $null | |
| } | |
| } | |
| Write-Host "========================================" -ForegroundColor Cyan | |
| Write-Host "Начало операции копирования стилей" -ForegroundColor Cyan | |
| Write-Host "========================================" -ForegroundColor Cyan | |
| Write-Host "" | |
| # Проверка файлов | |
| Write-Host "1. Проверка существования файлов..." -ForegroundColor Yellow | |
| foreach ($file in @($SourcePath, $TargetPath)) { | |
| if (-not (Test-Path -Path $file -PathType Leaf)) { | |
| Write-Error "❌ Файл не найден: $file" | |
| Exit 1 | |
| } else { | |
| $fileInfo = Get-Item $file | |
| Write-Host " ✓ Найден: $($fileInfo.Name) (размер: $([math]::Round($fileInfo.Length/1KB, 2)) КБ)" -ForegroundColor Green | |
| } | |
| } | |
| # Определение расширения исходного файла для временного файла | |
| $sourceExtension = [System.IO.Path]::GetExtension($SourcePath).ToLower() | |
| $targetExtension = [System.IO.Path]::GetExtension($TargetPath).ToLower() | |
| $supportedFormats = @('.docx', '.dotm', '.rtf', '.doc', '.dot') | |
| Write-Host "" | |
| Write-Host "2. Анализ форматов файлов..." -ForegroundColor Yellow | |
| Write-Host " Исходный файл: $sourceExtension" -ForegroundColor Gray | |
| Write-Host " Целевой файл: $targetExtension" -ForegroundColor Gray | |
| if ($sourceExtension -notin $supportedFormats) { | |
| Write-Error "❌ Неподдерживаемый формат исходного файла: $sourceExtension. Поддерживаются: $($supportedFormats -join ', ')" | |
| Exit 1 | |
| } | |
| if ($targetExtension -notin $supportedFormats) { | |
| Write-Error "❌ Неподдерживаемый формат целевого файла: $targetExtension. Поддерживаются: $($supportedFormats -join ', ')" | |
| Exit 1 | |
| } | |
| Write-Host " ✓ Форматы файлов поддерживаются" -ForegroundColor Green | |
| # Создание COM-объекта Word | |
| Write-Host "" | |
| Write-Host "3. Запуск Microsoft Word..." -ForegroundColor Yellow | |
| try { | |
| $wordApp = New-Object -ComObject Word.Application -ErrorAction Stop | |
| $wordVersion = $wordApp.Version | |
| Write-Host " ✓ Word запущен (версия: $wordVersion)" -ForegroundColor Green | |
| Write-Verbose "Word Application ID: $($wordApp.Application.ProcessID)" | |
| } catch { | |
| Write-Error "❌ Не удалось запустить Microsoft Word: $_" | |
| Exit 1 | |
| } | |
| $wordApp.Visible = $false | |
| $wordApp.DisplayAlerts = 0 # wdAlertsNone | |
| Write-Verbose "Word настроен: Visible=$($wordApp.Visible), DisplayAlerts=$($wordApp.DisplayAlerts)" | |
| $sourceDoc = $null | |
| $targetDoc = $null | |
| $tempDoc = $null | |
| $tempPath = $null | |
| try { | |
| # Открытие документов | |
| Write-Host "" | |
| Write-Host "4. Открытие документов..." -ForegroundColor Yellow | |
| Write-Host " Открытие документа-донора..." -ForegroundColor Gray | |
| $sourceFullPath = (Resolve-Path $SourcePath).Path | |
| Write-Verbose "Полный путь донора: $sourceFullPath" | |
| $sourceDoc = $wordApp.Documents.Open($sourceFullPath, $false, $true) # ReadOnly | |
| Write-Host " ✓ Документ-донор открыт" -ForegroundColor Green | |
| Write-Host " Количество стилей: $($sourceDoc.Styles.Count)" -ForegroundColor Gray | |
| Write-Host " Открытие целевого документа..." -ForegroundColor Gray | |
| $targetFullPath = (Resolve-Path $TargetPath).Path | |
| Write-Verbose "Полный путь целевого документа: $targetFullPath" | |
| $targetDoc = $wordApp.Documents.Open($targetFullPath) | |
| Write-Host " ✓ Целевой документ открыт" -ForegroundColor Green | |
| Write-Host " Количество стилей: $($targetDoc.Styles.Count)" -ForegroundColor Gray | |
| # Проверка существования всех указанных стилей | |
| Write-Host "" | |
| Write-Host "5. Проверка наличия запрошенных стилей в документе-доноре..." -ForegroundColor Yellow | |
| $missingStyles = @() | |
| $foundStyles = @() | |
| foreach ($styleName in $StyleNames) { | |
| $styleFound = $false | |
| foreach ($style in $sourceDoc.Styles) { | |
| if ($style.NameLocal -eq $styleName) { | |
| $styleFound = $true | |
| $foundStyles += $styleName | |
| Write-Host " ✓ Найден стиль: '$styleName'" -ForegroundColor Green | |
| Write-Verbose " Тип: $($style.Type), Встроенный: $($style.BuiltIn)" | |
| break | |
| } | |
| } | |
| if (-not $styleFound) { | |
| $missingStyles += $styleName | |
| Write-Host " ✗ Не найден стиль: '$styleName'" -ForegroundColor Red | |
| } | |
| } | |
| if ($missingStyles.Count -gt 0) { | |
| Write-Host "" | |
| Write-Host "Доступные стили в документе-доноре:" -ForegroundColor Yellow | |
| $sourceDoc.Styles | ForEach-Object { Write-Host " - $($_.NameLocal)" -ForegroundColor Gray } | |
| throw "Следующие стили не найдены в документе-доноре: $($missingStyles -join ', ')" | |
| } | |
| Write-Host "" | |
| Write-Host "6. Создание временного документа для переноса стилей..." -ForegroundColor Yellow | |
| # Генерируем путь к временному файлу с правильным расширением | |
| $timestamp = Get-Date -Format 'yyyyMMdd_HHmmss_fff' | |
| $tempFileName = "temp_style_copy_${timestamp}${sourceExtension}" | |
| $tempPath = Join-Path $env:TEMP $tempFileName | |
| Write-Host " Путь временного файла: $tempPath" -ForegroundColor Gray | |
| # ИЗМЕНЕНИЕ 1: Упрощенный подход - копирование файла напрямую | |
| Write-Host " Копирование файла-донора во временную папку..." -ForegroundColor Gray | |
| try { | |
| Copy-Item -Path $sourceFullPath -Destination $tempPath -Force | |
| Write-Host " ✓ Файл скопирован" -ForegroundColor Green | |
| # Проверяем, что файл создан | |
| if (Test-Path $tempPath) { | |
| $tempFileInfo = Get-Item $tempPath | |
| Write-Host " Размер: $([math]::Round($tempFileInfo.Length/1KB, 2)) КБ" -ForegroundColor Gray | |
| } else { | |
| throw "Временный файл не был создан по пути: $tempPath" | |
| } | |
| } catch { | |
| Write-Error "Ошибка при копировании файла: $_" | |
| throw | |
| } | |
| # Открываем временный документ | |
| Write-Host " Открытие временного документа..." -ForegroundColor Gray | |
| $tempDoc = $wordApp.Documents.Open($tempPath, $false, $false) | |
| Write-Verbose "Временный документ открыт" | |
| Write-Host "" | |
| Write-Host "7. Очистка временного документа от лишних стилей..." -ForegroundColor Yellow | |
| Write-Host " Всего стилей во временном документе: $($tempDoc.Styles.Count)" -ForegroundColor Gray | |
| # Подсчитываем стили для удаления | |
| $stylesToDelete = 0 | |
| $deletedStyles = 0 | |
| $keptStyles = 0 | |
| $failedToDelete = 0 | |
| foreach ($style in $tempDoc.Styles) { | |
| if ($StyleNames -notcontains $style.NameLocal) { | |
| $stylesToDelete++ | |
| } | |
| } | |
| Write-Host " Стилей для удаления: $stylesToDelete" -ForegroundColor Gray | |
| Write-Host " Стилей для сохранения: $($StyleNames.Count)" -ForegroundColor Gray | |
| # ИЗМЕНЕНИЕ 2: Более мягкий подход к удалению стилей | |
| # Удаляем только пользовательские стили, не трогая встроенные | |
| foreach ($style in $tempDoc.Styles) { | |
| $styleName = $style.NameLocal | |
| if ($StyleNames -notcontains $styleName) { | |
| # Пытаемся удалить только если стиль не встроенный | |
| if (-not $style.BuiltIn) { | |
| try { | |
| $style.Delete() | |
| $deletedStyles++ | |
| Write-Verbose " Удален стиль: '$styleName'" | |
| } catch { | |
| $failedToDelete++ | |
| Write-Verbose " Не удалось удалить стиль '$styleName': $_" | |
| } | |
| } else { | |
| Write-Verbose " Пропущен встроенный стиль: '$styleName'" | |
| } | |
| } else { | |
| $keptStyles++ | |
| Write-Host " ✓ Сохранен стиль: '$styleName'" -ForegroundColor Green | |
| } | |
| } | |
| Write-Host " Результат: удалено $deletedStyles, сохранено $keptStyles, не удалось удалить $failedToDelete стилей" -ForegroundColor Gray | |
| Write-Host " Сохранение изменений во временном файле..." -ForegroundColor Gray | |
| # ИЗМЕНЕНИЕ 3: Используем Save() вместо SaveAs2() для избежания проблем с форматом | |
| try { | |
| $tempDoc.Save() | |
| Write-Host " ✓ Изменения сохранены" -ForegroundColor Green | |
| } catch { | |
| Write-Warning "Не удалось сохранить изменения в временном файле: $_" | |
| Write-Host " Продолжаем без сохранения изменений..." -ForegroundColor Yellow | |
| } | |
| Write-Host "" | |
| Write-Host "8. Копирование стилей в целевой документ..." -ForegroundColor Yellow | |
| # ИЗМЕНЕНИЕ 4: Альтернативный метод копирования стилей | |
| # Если CopyStylesFromTemplate не работает, пробуем другой подход | |
| try { | |
| Write-Host " Попытка 1: Использование CopyStylesFromTemplate..." -ForegroundColor Gray | |
| $targetDoc.CopyStylesFromTemplate($tempDoc.FullName) | |
| Write-Host " ✓ Метод CopyStylesFromTemplate выполнен" -ForegroundColor Green | |
| } catch { | |
| Write-Warning "CopyStylesFromTemplate не сработал: $_" | |
| Write-Host " Попытка 2: Использование AttachedTemplate..." -ForegroundColor Gray | |
| try { | |
| # Временно подключаем документ как шаблон | |
| $originalTemplate = $targetDoc.AttachedTemplate | |
| $targetDoc.AttachedTemplate = $tempDoc.FullName | |
| $targetDoc.UpdateStyles() | |
| # Восстанавливаем оригинальный шаблон | |
| $targetDoc.AttachedTemplate = $originalTemplate | |
| Write-Host " ✓ Стили обновлены через AttachedTemplate" -ForegroundColor Green | |
| } catch { | |
| Write-Warning "AttachedTemplate не сработал: $_" | |
| # ИЗМЕНЕНИЕ 5: Последний резервный вариант - копирование стилей по одному | |
| Write-Host " Попытка 3: Копирование стилей по одному..." -ForegroundColor Gray | |
| $copiedCount = 0 | |
| foreach ($styleName in $StyleNames) { | |
| try { | |
| # Находим стиль в исходном документе | |
| $sourceStyle = $null | |
| foreach ($style in $sourceDoc.Styles) { | |
| if ($style.NameLocal -eq $styleName) { | |
| $sourceStyle = $style | |
| break | |
| } | |
| } | |
| if ($sourceStyle) { | |
| # Проверяем, существует ли стиль в целевом документе | |
| $targetStyle = $null | |
| foreach ($style in $targetDoc.Styles) { | |
| if ($style.NameLocal -eq $styleName) { | |
| $targetStyle = $style | |
| break | |
| } | |
| } | |
| if (-not $targetStyle) { | |
| # Создаем новый стиль в целевом документе | |
| $targetStyle = $targetDoc.Styles.Add($styleName, $sourceStyle.Type) | |
| } | |
| # Копируем свойства стиля | |
| $targetStyle.Font.Name = $sourceStyle.Font.Name | |
| $targetStyle.Font.Size = $sourceStyle.Font.Size | |
| $targetStyle.Font.Bold = $sourceStyle.Font.Bold | |
| $targetStyle.Font.Italic = $sourceStyle.Font.Italic | |
| $targetStyle.Font.Color = $sourceStyle.Font.Color | |
| if ($sourceStyle.Type -eq 1) { # wdStyleTypeParagraph | |
| $targetStyle.ParagraphFormat.Alignment = $sourceStyle.ParagraphFormat.Alignment | |
| $targetStyle.ParagraphFormat.LeftIndent = $sourceStyle.ParagraphFormat.LeftIndent | |
| $targetStyle.ParagraphFormat.RightIndent = $sourceStyle.ParagraphFormat.RightIndent | |
| $targetStyle.ParagraphFormat.SpaceBefore = $sourceStyle.ParagraphFormat.SpaceBefore | |
| $targetStyle.ParagraphFormat.SpaceAfter = $sourceStyle.ParagraphFormat.SpaceAfter | |
| $targetStyle.ParagraphFormat.LineSpacing = $sourceStyle.ParagraphFormat.LineSpacing | |
| } | |
| $copiedCount++ | |
| Write-Host " ✓ Скопирован стиль: '$styleName'" -ForegroundColor Green | |
| } | |
| } catch { | |
| Write-Warning " Не удалось скопировать стиль '$styleName': $_" | |
| } | |
| } | |
| if ($copiedCount -gt 0) { | |
| Write-Host " ✓ Скопировано стилей: $copiedCount из $($StyleNames.Count)" -ForegroundColor Green | |
| } else { | |
| throw "Не удалось скопировать ни одного стиля" | |
| } | |
| } | |
| } | |
| # Проверяем наличие скопированных стилей | |
| Write-Host "" | |
| Write-Host "9. Проверка результата копирования..." -ForegroundColor Yellow | |
| $successCount = 0 | |
| foreach ($styleName in $StyleNames) { | |
| $found = $false | |
| foreach ($style in $targetDoc.Styles) { | |
| if ($style.NameLocal -eq $styleName) { | |
| $found = $true | |
| $successCount++ | |
| Write-Host " ✓ Стиль '$styleName' присутствует в целевом документе" -ForegroundColor Green | |
| break | |
| } | |
| } | |
| if (-not $found) { | |
| Write-Host " ⚠ Стиль '$styleName' не найден в целевом документе" -ForegroundColor Yellow | |
| } | |
| } | |
| Write-Host "" | |
| Write-Host "========================================" -ForegroundColor Green | |
| Write-Host "✓ Операция завершена успешно!" -ForegroundColor Green | |
| Write-Host " Скопировано стилей: $successCount из $($StyleNames.Count)" -ForegroundColor Green | |
| Write-Host "========================================" -ForegroundColor Green | |
| } | |
| catch { | |
| Write-Host "" | |
| Write-Host "========================================" -ForegroundColor Red | |
| Write-Host "❌ ОШИБКА!" -ForegroundColor Red | |
| Write-Host "========================================" -ForegroundColor Red | |
| Write-Error "Детали ошибки: $($_.Exception.Message)" | |
| Write-Verbose "Stack trace: $($_.ScriptStackTrace)" | |
| if ($_.Exception.InnerException) { | |
| Write-Verbose "Inner exception: $($_.Exception.InnerException.Message)" | |
| } | |
| } | |
| finally { | |
| Write-Host "" | |
| Write-Host "10. Очистка ресурсов..." -ForegroundColor Yellow | |
| # Закрытие временного документа | |
| if ($tempDoc) { | |
| Write-Host " Закрытие временного документа..." -ForegroundColor Gray | |
| try { | |
| $tempDoc.Close($false) | |
| Write-Host " ✓ Временный документ закрыт" -ForegroundColor Green | |
| } catch { | |
| Write-Host " ⚠ Ошибка при закрытии временного документа: $_" -ForegroundColor Yellow | |
| } | |
| Release-ComObject ([ref]$tempDoc) | |
| } | |
| # Закрытие целевого документа с сохранением | |
| if ($targetDoc) { | |
| Write-Host " Сохранение и закрытие целевого документа..." -ForegroundColor Gray | |
| try { | |
| $targetDoc.Close($true) | |
| Write-Host " ✓ Целевой документ сохранен и закрыт" -ForegroundColor Green | |
| } catch { | |
| Write-Host " ⚠ Ошибка при закрытии целевого документа: $_" -ForegroundColor Yellow | |
| } | |
| Release-ComObject ([ref]$targetDoc) | |
| } | |
| # Закрытие документа-донор без сохранения | |
| if ($sourceDoc) { | |
| Write-Host " Закрытие документа-донора..." -ForegroundColor Gray | |
| try { | |
| $sourceDoc.Close($false) | |
| Write-Host " ✓ Документ-донор закрыт" -ForegroundColor Green | |
| } catch { | |
| Write-Host " ⚠ Ошибка при закрытии документа-донора: $_" -ForegroundColor Yellow | |
| } | |
| Release-ComObject ([ref]$sourceDoc) | |
| } | |
| # Завершение Word | |
| if ($wordApp) { | |
| Write-Host " Завершение Microsoft Word..." -ForegroundColor Gray | |
| try { | |
| $wordApp.Quit() | |
| Write-Host " ✓ Word завершен" -ForegroundColor Green | |
| } catch { | |
| Write-Host " ⚠ Ошибка при завершении Word: $_" -ForegroundColor Yellow | |
| } | |
| Release-ComObject ([ref]$wordApp) | |
| } | |
| # Удаление временного файла | |
| if ($tempPath -and (Test-Path $tempPath)) { | |
| Write-Host " Удаление временного файла..." -ForegroundColor Gray | |
| try { | |
| Remove-Item $tempPath -ErrorAction Stop | |
| Write-Host " ✓ Временный файл удален" -ForegroundColor Green | |
| } catch { | |
| Write-Host " ⚠ Не удалось удалить временный файл: $_" -ForegroundColor Yellow | |
| Write-Host " Путь: $tempPath" -ForegroundColor Gray | |
| } | |
| } | |
| Write-Host "" | |
| Write-Host "========================================" -ForegroundColor Cyan | |
| Write-Host "Завершение работы скрипта" -ForegroundColor Cyan | |
| Write-Host "========================================" -ForegroundColor Cyan | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment