Last active
November 19, 2025 06:17
-
-
Save nsdevaraj/aefbb928c4c479609c0598d207f4e2af to your computer and use it in GitHub Desktop.
convert pbix
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
| # PBIX Converter Utility | |
| # Converts PBIX files by modifying visual types and removing SecurityBindings | |
| param( | |
| [Parameter(Mandatory=$true, Position=0)] | |
| [string]$InputFile, | |
| [Parameter(Mandatory=$false, Position=1)] | |
| [string]$OutputFile | |
| ) | |
| # Function to print colored messages | |
| function Write-Info { | |
| param([string]$Message) | |
| Write-Host "[INFO] $Message" -ForegroundColor Green | |
| } | |
| function Write-Error-Custom { | |
| param([string]$Message) | |
| Write-Host "[ERROR] $Message" -ForegroundColor Red | |
| } | |
| function Write-Warning-Custom { | |
| param([string]$Message) | |
| Write-Host "[WARNING] $Message" -ForegroundColor Yellow | |
| } | |
| function Show-Usage { | |
| Write-Host "Usage: .\convert-pbix.ps1 <input.pbix> [output.pbix]" | |
| Write-Host "" | |
| Write-Host "Arguments:" | |
| Write-Host " input.pbix - Path to the input PBIX file" | |
| Write-Host " output.pbix - (Optional) Path to the output PBIX file" | |
| Write-Host " If not specified, will create '<input>_converted.pbix'" | |
| Write-Host "" | |
| Write-Host "Example:" | |
| Write-Host " .\convert-pbix.ps1 myreport.pbix" | |
| Write-Host " .\convert-pbix.ps1 myreport.pbix myreport_modified.pbix" | |
| exit 1 | |
| } | |
| # Check if input file exists | |
| if (-not (Test-Path $InputFile)) { | |
| Write-Error-Custom "Input file '$InputFile' not found" | |
| exit 1 | |
| } | |
| # Check if input file is a PBIX file | |
| if ([System.IO.Path]::GetExtension($InputFile) -ne ".pbix") { | |
| Write-Error-Custom "Input file must have .pbix extension" | |
| exit 1 | |
| } | |
| # Determine output file name | |
| if ([string]::IsNullOrEmpty($OutputFile)) { | |
| $inputFileObj = Get-Item $InputFile | |
| $OutputFile = Join-Path $inputFileObj.DirectoryName ($inputFileObj.BaseName + "_converted.pbix") | |
| } else { | |
| $OutputFile = [System.IO.Path]::GetFullPath($OutputFile) | |
| } | |
| # Get absolute path for input file | |
| $InputFile = [System.IO.Path]::GetFullPath($InputFile) | |
| Write-Info "Starting PBIX conversion" | |
| Write-Info "Input file: $InputFile" | |
| Write-Info "Output file: $OutputFile" | |
| # Create temporary directory (cross-platform) | |
| $TempBase = if ($env:TEMP) { $env:TEMP } elseif ($env:TMPDIR) { $env:TMPDIR } else { "/tmp" } | |
| $TempDir = Join-Path $TempBase ("pbix-converter-" + [System.IO.Path]::GetRandomFileName()) | |
| New-Item -ItemType Directory -Path $TempDir -Force | Out-Null | |
| Write-Info "Created temporary directory: $TempDir" | |
| try { | |
| # Step 1-2: Extract PBIX file | |
| Write-Info "Step 1-2: Extracting PBIX file..." | |
| try { | |
| Expand-Archive -Path $InputFile -DestinationPath $TempDir -Force | |
| } catch { | |
| Write-Error-Custom "Failed to extract PBIX file: $_" | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| exit 1 | |
| } | |
| # Step 3: Remove SecurityBindings file | |
| Write-Info "Step 3: Removing SecurityBindings file..." | |
| $securityBindingsPath = Join-Path $TempDir "SecurityBindings" | |
| if (Test-Path $securityBindingsPath) { | |
| Remove-Item -Path $securityBindingsPath -Force | |
| Write-Info "SecurityBindings file removed" | |
| } else { | |
| Write-Warning-Custom "SecurityBindings file not found (this may be expected)" | |
| } | |
| # Step 4-5: Edit Layout file | |
| Write-Info "Step 4-5: Modifying Layout file..." | |
| $layoutPath = Join-Path $TempDir "Report\Layout" | |
| if (Test-Path $layoutPath) { | |
| # Create backup | |
| Copy-Item -Path $layoutPath -Destination "$layoutPath.backup" -Force | |
| Write-Info " - Converting Layout from UTF-16LE to UTF-8..." | |
| Write-Info " - Replacing pivotTable visual type..." | |
| Write-Info " - Replacing tableEx visual type..." | |
| Write-Info " - Replacing projections Values with ameasure..." | |
| Write-Info " - Replacing Rows with rows..." | |
| Write-Info " - Replacing Columns with columns..." | |
| Write-Info " - Adding publicCustomVisuals declaration..." | |
| Write-Info " - Converting Layout back to UTF-16LE..." | |
| try { | |
| # Read file as UTF-16LE | |
| $content = [System.IO.File]::ReadAllText($layoutPath, [System.Text.Encoding]::Unicode) | |
| # Perform replacements | |
| $content = $content.Replace( | |
| '{\"visualType\":\"pivotTable\"', | |
| '{\"visualType\":\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\"' | |
| ) | |
| $content = $content.Replace( | |
| '{\"visualType\":\"tableEx\"', | |
| '{\"visualType\":\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\"' | |
| ) | |
| $content = $content.Replace( | |
| 'projections\":{\"Values\":', | |
| 'projections\":{\"ameasure\":' | |
| ) | |
| $content = $content.Replace( | |
| '\\"Rows\\":[', | |
| '\\"rows\\":[' | |
| ) | |
| $content = $content.Replace( | |
| '\\"Columns\\":[', | |
| '\\"columns\\":[' | |
| ) | |
| # Add publicCustomVisuals declaration | |
| $content = $content.TrimEnd('}') + ',\"publicCustomVisuals\":[\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\"]}' | |
| # Write back as UTF-16LE | |
| [System.IO.File]::WriteAllText($layoutPath, $content, [System.Text.Encoding]::Unicode) | |
| Write-Info "Layout file modified successfully" | |
| } catch { | |
| Write-Error-Custom "Failed to modify Layout file: $_" | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| exit 1 | |
| } | |
| } else { | |
| Write-Error-Custom "Layout file not found at $layoutPath" | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| exit 1 | |
| } | |
| # Step 6: Create new PBIX file | |
| Write-Info "Step 6: Creating new PBIX file..." | |
| # Remove old output file if it exists | |
| if (Test-Path $OutputFile) { | |
| Remove-Item -Path $OutputFile -Force | |
| } | |
| try { | |
| # Get all files except backups and .DS_Store | |
| $filesToZip = Get-ChildItem -Path $TempDir -Recurse -File | | |
| Where-Object { $_.Name -notmatch '\.backup$' -and $_.Name -ne '.DS_Store' } | |
| # Create ZIP file | |
| Add-Type -AssemblyName System.IO.Compression.FileSystem | |
| $zip = [System.IO.Compression.ZipFile]::Open($OutputFile, 'Create') | |
| foreach ($file in $filesToZip) { | |
| $relativePath = $file.FullName.Substring($TempDir.Length + 1).Replace('\', '/') | |
| [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip, $file.FullName, $relativePath, 'Optimal') | Out-Null | |
| } | |
| $zip.Dispose() | |
| Write-Info "✓ Conversion completed successfully!" | |
| Write-Info "Output file: $OutputFile" | |
| Write-Host "" | |
| Write-Host "Summary of changes:" | |
| Write-Host " - SecurityBindings file removed (if present)" | |
| Write-Host " - pivotTable visuals -> inforiverAppPremium" | |
| Write-Host " - tableEx visuals -> inforiverAppPremium" | |
| } catch { | |
| Write-Error-Custom "Failed to create PBIX file: $_" | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| exit 1 | |
| } | |
| } finally { | |
| # Cleanup | |
| Write-Info "Cleaning up temporary files..." | |
| if (Test-Path $TempDir) { | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| } | |
| } | |
| exit 0 |
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
| # PBIX Converter Utility | |
| # Converts PBIX files by modifying visual types and removing SecurityBindings | |
| # Fix the line endings | |
| # (Get-Content "convert_windows_CRLF 1.ps1" -Raw) -replace "`r`r`n","`r`n" | Set-Content "convert_windows_CRLF_fixed.ps1" -NoNewline | |
| param( | |
| [Parameter(Mandatory=$true, Position=0)] | |
| [string]$InputFile, | |
| [Parameter(Mandatory=$false, Position=1)] | |
| [string]$OutputFile | |
| ) | |
| # Function to print colored messages | |
| function Write-Info { | |
| param([string]$Message) | |
| Write-Host "[INFO] $Message" -ForegroundColor Green | |
| } | |
| function Write-Error-Custom { | |
| param([string]$Message) | |
| Write-Host "[ERROR] $Message" -ForegroundColor Red | |
| } | |
| function Write-Warning-Custom { | |
| param([string]$Message) | |
| Write-Host "[WARNING] $Message" -ForegroundColor Yellow | |
| } | |
| function Show-Usage { | |
| Write-Host "Usage: .\convert-pbix.ps1 <input.pbix> [output.pbix]" | |
| Write-Host "" | |
| Write-Host "Arguments:" | |
| Write-Host " input.pbix - Path to the input PBIX file" | |
| Write-Host " output.pbix - (Optional) Path to the output PBIX file" | |
| Write-Host " If not specified, will create '<input>_converted.pbix'" | |
| Write-Host "" | |
| Write-Host "Example:" | |
| Write-Host " .\convert-pbix.ps1 myreport.pbix" | |
| Write-Host " .\convert-pbix.ps1 myreport.pbix myreport_modified.pbix" | |
| exit 1 | |
| } | |
| # Check if input file exists | |
| if (-not (Test-Path $InputFile)) { | |
| Write-Error-Custom "Input file '$InputFile' not found" | |
| exit 1 | |
| } | |
| # Check if input file is a PBIX file | |
| if ([System.IO.Path]::GetExtension($InputFile) -ne ".pbix") { | |
| Write-Error-Custom "Input file must have .pbix extension" | |
| exit 1 | |
| } | |
| # Determine output file name | |
| if ([string]::IsNullOrEmpty($OutputFile)) { | |
| $inputFileObj = Get-Item $InputFile | |
| $OutputFile = Join-Path $inputFileObj.DirectoryName ($inputFileObj.BaseName + "_converted.pbix") | |
| } else { | |
| $OutputFile = [System.IO.Path]::GetFullPath($OutputFile) | |
| } | |
| # Get absolute path for input file | |
| $InputFile = [System.IO.Path]::GetFullPath($InputFile) | |
| Write-Info "Starting PBIX conversion" | |
| Write-Info "Input file: $InputFile" | |
| Write-Info "Output file: $OutputFile" | |
| # Create temporary directory (cross-platform) | |
| $TempBase = if ($env:TEMP) { $env:TEMP } elseif ($env:TMPDIR) { $env:TMPDIR } else { "/tmp" } | |
| $TempDir = Join-Path $TempBase ("pbix-converter-" + [System.IO.Path]::GetRandomFileName()) | |
| New-Item -ItemType Directory -Path $TempDir -Force | Out-Null | |
| Write-Info "Created temporary directory: $TempDir" | |
| try { | |
| # Step 1-2: Extract PBIX file | |
| Write-Info "Step 1-2: Extracting PBIX file..." | |
| try { | |
| # Copy PBIX file to temp location with .zip extension | |
| # (PBIX is a ZIP file, but Expand-Archive may require .zip extension) | |
| $tempZipPath = Join-Path $TempDir "temp.zip" | |
| Copy-Item -Path $InputFile -Destination $tempZipPath -Force | |
| # Extract the ZIP file | |
| Expand-Archive -Path $tempZipPath -DestinationPath $TempDir -Force | |
| # Remove the temporary zip file | |
| Remove-Item -Path $tempZipPath -Force | |
| } catch { | |
| Write-Error-Custom "Failed to extract PBIX file: $_" | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| exit 1 | |
| } | |
| # Step 3: Remove SecurityBindings file | |
| Write-Info "Step 3: Removing SecurityBindings file..." | |
| $securityBindingsPath = Join-Path $TempDir "SecurityBindings" | |
| if (Test-Path $securityBindingsPath) { | |
| Remove-Item -Path $securityBindingsPath -Force | |
| Write-Info "SecurityBindings file removed" | |
| } else { | |
| Write-Warning-Custom "SecurityBindings file not found (this may be expected)" | |
| } | |
| # Step 4-5: Edit Layout file | |
| Write-Info "Step 4-5: Modifying Layout file..." | |
| $layoutPath = Join-Path $TempDir "Report\Layout" | |
| if (Test-Path $layoutPath) { | |
| # Create backup | |
| Copy-Item -Path $layoutPath -Destination "$layoutPath.backup" -Force | |
| Write-Info " - Converting Layout from UTF-16LE to UTF-8..." | |
| Write-Info " - Replacing pivotTable visual type..." | |
| Write-Info " - Replacing tableEx visual type..." | |
| Write-Info " - Replacing projections Values with ameasure..." | |
| Write-Info " - Replacing Rows with rows..." | |
| Write-Info " - Replacing Columns with columns..." | |
| Write-Info " - Adding publicCustomVisuals declaration..." | |
| Write-Info " - Converting Layout back to UTF-16LE..." | |
| try { | |
| # Read file as UTF-16LE | |
| $content = [System.IO.File]::ReadAllText($layoutPath, [System.Text.Encoding]::Unicode) | |
| # Perform replacements | |
| $content = $content.Replace( | |
| '{\"visualType\":\"pivotTable\"', | |
| '{\"visualType\":\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\"' | |
| ) | |
| $content = $content.Replace( | |
| '{\"visualType\":\"tableEx\"', | |
| '{\"visualType\":\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\"' | |
| ) | |
| $content = $content.Replace( | |
| 'projections\":{\"Values\":', | |
| 'projections\":{\"ameasure\":' | |
| ) | |
| $content = $content.Replace( | |
| '\\"Rows\\":[', | |
| '\\"rows\\":[' | |
| ) | |
| $content = $content.Replace( | |
| '\\"Columns\\":[', | |
| '\\"columns\\":[' | |
| ) | |
| # Add publicCustomVisuals declaration | |
| $content = $content.TrimEnd('}') + ',\"publicCustomVisuals\":[\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\"]}' | |
| # Write back as UTF-16LE | |
| [System.IO.File]::WriteAllText($layoutPath, $content, [System.Text.Encoding]::Unicode) | |
| Write-Info "Layout file modified successfully" | |
| } catch { | |
| Write-Error-Custom "Failed to modify Layout file: $_" | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| exit 1 | |
| } | |
| } else { | |
| Write-Error-Custom "Layout file not found at $layoutPath" | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| exit 1 | |
| } | |
| # Step 6: Create new PBIX file | |
| Write-Info "Step 6: Creating new PBIX file..." | |
| # Remove old output file if it exists | |
| if (Test-Path $OutputFile) { | |
| Remove-Item -Path $OutputFile -Force | |
| } | |
| try { | |
| # Get all files except backups and .DS_Store | |
| $filesToZip = Get-ChildItem -Path $TempDir -Recurse -File | | |
| Where-Object { $_.Name -notmatch '\.backup$' -and $_.Name -ne '.DS_Store' } | |
| # Create ZIP file | |
| Add-Type -AssemblyName System.IO.Compression.FileSystem | |
| $zip = [System.IO.Compression.ZipFile]::Open($OutputFile, 'Create') | |
| foreach ($file in $filesToZip) { | |
| $relativePath = $file.FullName.Substring($TempDir.Length + 1).Replace('\', '/') | |
| [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip, $file.FullName, $relativePath, 'Optimal') | Out-Null | |
| } | |
| $zip.Dispose() | |
| Write-Info "✓ Conversion completed successfully!" | |
| Write-Info "Output file: $OutputFile" | |
| Write-Host "" | |
| Write-Host "Summary of changes:" | |
| Write-Host " - SecurityBindings file removed (if present)" | |
| Write-Host " - pivotTable visuals -> inforiverAppPremium" | |
| Write-Host " - tableEx visuals -> inforiverAppPremium" | |
| } catch { | |
| Write-Error-Custom "Failed to create PBIX file: $_" | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| exit 1 | |
| } | |
| } finally { | |
| # Cleanup | |
| Write-Info "Cleaning up temporary files..." | |
| if (Test-Path $TempDir) { | |
| Remove-Item -Path $TempDir -Recurse -Force | |
| } | |
| } | |
| exit 0 |
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
| step 1: | |
| rename pbix to zip | |
| step 2: extract zip | |
| step 3: delete SecurityBindings file from zip | |
| step 4: Edit Layout file, look for {\"visualType\":\"pivotTable\", replace all instances with {\"visualType\":\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\", | |
| step 5: Edit Layout file, look for {\"visualType\":\"tableEx\", replace all instances with {\"visualType\":\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\", |
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
| pivotTable | |
| tableEx | |
| {\"visualType\":\"pivotTable\", | |
| {\"visualType\":\"tableEx\", | |
| {\"visualType\":\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\", |
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
| @echo off | |
| setlocal enabledelayedexpansion | |
| REM PBIX Converter Utility | |
| REM Converts PBIX files by modifying visual types and removing SecurityBindings | |
| REM Function to print colored messages | |
| set "INFO_COLOR=0A" | |
| set "ERROR_COLOR=0C" | |
| set "WARNING_COLOR=0E" | |
| :print_info | |
| echo [INFO] %~1 | |
| goto :eof | |
| :print_error | |
| echo [ERROR] %~1 | |
| goto :eof | |
| :print_warning | |
| echo [WARNING] %~1 | |
| goto :eof | |
| :usage | |
| echo Usage: %~nx0 ^<input.pbix^> [output.pbix] | |
| echo. | |
| echo Arguments: | |
| echo input.pbix - Path to the input PBIX file | |
| echo output.pbix - (Optional) Path to the output PBIX file | |
| echo If not specified, will create '^<input^>_converted.pbix' | |
| echo. | |
| echo Example: | |
| echo %~nx0 myreport.pbix | |
| echo %~nx0 myreport.pbix myreport_modified.pbix | |
| exit /b 1 | |
| REM Check if input file is provided | |
| if "%~1"=="" ( | |
| call :print_error "No input file specified" | |
| call :usage | |
| ) | |
| set "INPUT_FILE=%~1" | |
| REM Check if input file exists | |
| if not exist "!INPUT_FILE!" ( | |
| call :print_error "Input file '!INPUT_FILE!' not found" | |
| exit /b 1 | |
| ) | |
| REM Check if input file is a PBIX file | |
| if /i not "%~x1"==".pbix" ( | |
| call :print_error "Input file must have .pbix extension" | |
| exit /b 1 | |
| ) | |
| REM Determine output file name | |
| if "%~2"=="" ( | |
| set "OUTPUT_FILE=%~dpn1_converted.pbix" | |
| ) else ( | |
| set "OUTPUT_FILE=%~2" | |
| ) | |
| REM Get absolute path for output file | |
| for %%i in ("!OUTPUT_FILE!") do set "OUTPUT_FILE=%%~fi" | |
| call :print_info "Starting PBIX conversion" | |
| call :print_info "Input file: !INPUT_FILE!" | |
| call :print_info "Output file: !OUTPUT_FILE!" | |
| REM Create temporary directory | |
| set "TEMP_DIR=%TEMP%\pbix-converter-%RANDOM%%RANDOM%" | |
| mkdir "!TEMP_DIR!" | |
| call :print_info "Created temporary directory: !TEMP_DIR!" | |
| REM Step 1-2: Extract PBIX file | |
| call :print_info "Step 1-2: Extracting PBIX file..." | |
| cd /d "!TEMP_DIR!" | |
| REM Use PowerShell to unzip (available on Windows 10+) | |
| powershell -Command "Expand-Archive -Path '%INPUT_FILE%' -DestinationPath '.' -Force" >nul 2>&1 | |
| if errorlevel 1 ( | |
| call :print_error "Failed to extract PBIX file" | |
| rmdir /s /q "!TEMP_DIR!" | |
| exit /b 1 | |
| ) | |
| REM Step 3: Remove SecurityBindings file | |
| call :print_info "Step 3: Removing SecurityBindings file..." | |
| if exist "SecurityBindings" ( | |
| del /f /q "SecurityBindings" | |
| call :print_info "SecurityBindings file removed" | |
| ) else ( | |
| call :print_warning "SecurityBindings file not found (this may be expected)" | |
| ) | |
| REM Step 4-5: Edit Layout file | |
| call :print_info "Step 4-5: Modifying Layout file..." | |
| set "LAYOUT_FILE=Report\Layout" | |
| if exist "!LAYOUT_FILE!" ( | |
| REM Create backup | |
| copy "!LAYOUT_FILE!" "!LAYOUT_FILE!.backup" >nul | |
| REM Convert UTF-16LE to UTF-8, perform replacements, and convert back using Python | |
| call :print_info " - Converting Layout from UTF-16LE to UTF-8..." | |
| call :print_info " - Replacing pivotTable visual type..." | |
| call :print_info " - Replacing tableEx visual type..." | |
| call :print_info " - Adding publicCustomVisuals declaration..." | |
| call :print_info " - Converting Layout back to UTF-16LE..." | |
| python -c "import sys; data = open(r'!LAYOUT_FILE!', 'rb').read().decode('utf-16le'); data = data.replace(r'{\\\"visualType\\\":\\\"pivotTable\\\"', r'{\\\"visualType\\\":\\\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\\\"'); data = data.replace(r'{\\\"visualType\\\":\\\"tableEx\\\"', r'{\\\"visualType\\\":\\\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\\\"'); data = data.rstrip('}') + ',\"publicCustomVisuals\":[\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\"]}'; open(r'!LAYOUT_FILE!', 'wb').write(data.encode('utf-16le'))" | |
| if errorlevel 1 ( | |
| call :print_error "Failed to modify Layout file" | |
| cd /d "%~dp0" | |
| rmdir /s /q "!TEMP_DIR!" | |
| exit /b 1 | |
| ) | |
| call :print_info "Layout file modified successfully" | |
| ) else ( | |
| call :print_error "Layout file not found at !LAYOUT_FILE!" | |
| cd /d "%~dp0" | |
| rmdir /s /q "!TEMP_DIR!" | |
| exit /b 1 | |
| ) | |
| REM Step 6: Create new PBIX file | |
| call :print_info "Step 6: Creating new PBIX file..." | |
| REM Remove old output file if it exists | |
| if exist "!OUTPUT_FILE!" del /f /q "!OUTPUT_FILE!" | |
| REM Create PBIX using Python to ensure Windows-compatible ZIP format | |
| python -c "import os; import zipfile; import sys; from time import localtime; files_to_add = []; [files_to_add.extend([(os.path.join(root, file), os.path.relpath(os.path.join(root, file), '.')) for file in files if not file.endswith('.backup') and file != '.DS_Store']) for root, dirs, files in os.walk('.')]; zipf = zipfile.ZipFile(r'!OUTPUT_FILE!', 'w', zipfile.ZIP_DEFLATED); [zipf.writestr(zipfile.ZipInfo(filename=arcname, date_time=localtime(os.stat(file_path).st_mtime)[:6], compress_type=zipfile.ZIP_DEFLATED, create_system=0, external_attr=0o644 << 16), open(file_path, 'rb').read()) for file_path, arcname in files_to_add]; zipf.close()" | |
| if errorlevel 1 ( | |
| call :print_error "Failed to create PBIX file" | |
| cd /d "%~dp0" | |
| rmdir /s /q "!TEMP_DIR!" | |
| exit /b 1 | |
| ) | |
| call :print_info "� Conversion completed successfully!" | |
| call :print_info "Output file: !OUTPUT_FILE!" | |
| echo. | |
| echo Summary of changes: | |
| echo - SecurityBindings file removed (if present) | |
| echo - pivotTable visuals -^> inforiverAppPremium | |
| echo - tableEx visuals -^> inforiverAppPremium | |
| REM Cleanup | |
| call :print_info "Cleaning up temporary files..." | |
| cd /d "%~dp0" | |
| rmdir /s /q "!TEMP_DIR!" | |
| exit /b 0 |
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
| #!/bin/bash | |
| # PBIX Converter Utility | |
| # Converts PBIX files by modifying visual types and removing SecurityBindings | |
| set -e # Exit on error | |
| # Color codes for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| NC='\033[0m' # No Color | |
| # Function to print colored messages | |
| print_info() { | |
| echo -e "${GREEN}[INFO]${NC} $1" | |
| } | |
| print_error() { | |
| echo -e "${RED}[ERROR]${NC} $1" | |
| } | |
| print_warning() { | |
| echo -e "${YELLOW}[WARNING]${NC} $1" | |
| } | |
| # Function to display usage | |
| usage() { | |
| echo "Usage: $0 <input.pbix> [output.pbix]" | |
| echo "" | |
| echo "Arguments:" | |
| echo " input.pbix - Path to the input PBIX file" | |
| echo " output.pbix - (Optional) Path to the output PBIX file" | |
| echo " If not specified, will create '<input>_converted.pbix'" | |
| echo "" | |
| echo "Example:" | |
| echo " $0 myreport.pbix" | |
| echo " $0 myreport.pbix myreport_modified.pbix" | |
| exit 1 | |
| } | |
| # Check if input file is provided | |
| if [ $# -eq 0 ]; then | |
| print_error "No input file provided" | |
| usage | |
| fi | |
| INPUT_FILE="$1" | |
| OUTPUT_FILE="${2:-}" | |
| # Validate input file | |
| if [ ! -f "$INPUT_FILE" ]; then | |
| print_error "Input file '$INPUT_FILE' does not exist" | |
| exit 1 | |
| fi | |
| # Check if input file has .pbix extension | |
| if [[ ! "$INPUT_FILE" =~ \.pbix$ ]]; then | |
| print_error "Input file must have .pbix extension" | |
| exit 1 | |
| fi | |
| # Set output file if not provided | |
| if [ -z "$OUTPUT_FILE" ]; then | |
| BASENAME="${INPUT_FILE%.pbix}" | |
| OUTPUT_FILE="${BASENAME}_converted.pbix" | |
| fi | |
| print_info "Starting PBIX conversion" | |
| print_info "Input file: $INPUT_FILE" | |
| print_info "Output file: $OUTPUT_FILE" | |
| # Create a temporary directory for extraction | |
| TEMP_DIR=$(mktemp -d -t pbix-converter-XXXXXX) | |
| print_info "Created temporary directory: $TEMP_DIR" | |
| # Cleanup function | |
| cleanup() { | |
| print_info "Cleaning up temporary files..." | |
| rm -rf "$TEMP_DIR" | |
| } | |
| # Set trap to cleanup on exit | |
| trap cleanup EXIT | |
| # Step 1 & 2: Copy to temp dir and extract | |
| print_info "Step 1-2: Extracting PBIX file..." | |
| cp "$INPUT_FILE" "$TEMP_DIR/temp.zip" | |
| cd "$TEMP_DIR" | |
| unzip -q temp.zip | |
| rm temp.zip | |
| # Step 3: Delete SecurityBindings file | |
| print_info "Step 3: Removing SecurityBindings file..." | |
| if [ -f "SecurityBindings" ]; then | |
| rm SecurityBindings | |
| print_info "SecurityBindings file removed" | |
| else | |
| print_warning "SecurityBindings file not found (this may be expected)" | |
| fi | |
| # Step 4 & 5: Edit Layout file | |
| print_info "Step 4-5: Modifying Layout file..." | |
| LAYOUT_FILE="Report/Layout" | |
| if [ -f "$LAYOUT_FILE" ]; then | |
| # Create backup | |
| cp "$LAYOUT_FILE" "${LAYOUT_FILE}.backup" | |
| # Layout file is UTF-16LE encoded, need to convert to UTF-8, replace, then convert back | |
| print_info " - Converting Layout from UTF-16LE to UTF-8..." | |
| iconv -f UTF-16LE -t UTF-8 "$LAYOUT_FILE" > "${LAYOUT_FILE}.utf8" | |
| # Replace pivotTable visual type (note: JSON is escaped with backslashes in the file) | |
| print_info " - Replacing pivotTable visual type..." | |
| sed -i '' 's/{\\"visualType\\":\\"pivotTable\\"/{\\"visualType\\":\\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\\"/g' "${LAYOUT_FILE}.utf8" | |
| # Replace tableEx visual type (note: JSON is escaped with backslashes in the file) | |
| print_info " - Replacing tableEx visual type..." | |
| sed -i '' 's/{\\"visualType\\":\\"tableEx\\"/{\\"visualType\\":\\"inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B\\"/g' "${LAYOUT_FILE}.utf8" | |
| # Replace projections Values with ameasure | |
| print_info " - Replacing projections Values with ameasure..." | |
| sed -i '' 's/projections\\":{\\"\Values\\":/projections\\":{\\"\ameasure\\":/g' "${LAYOUT_FILE}.utf8" | |
| # Replace Rows with rows | |
| print_info " - Replacing Rows with rows..." | |
| sed -i '' 's/\\"Rows\\":/\\"rows\\":/g' "${LAYOUT_FILE}.utf8" | |
| # Replace Columns with columns | |
| print_info " - Replacing Columns with columns..." | |
| sed -i '' 's/\\"Columns\\":/\\"columns\\":/g' "${LAYOUT_FILE}.utf8" | |
| # Add publicCustomVisuals array at the end (replace last } with the array declaration) | |
| print_info " - Adding publicCustomVisuals declaration..." | |
| sed -i '' '$ s/}$/,"publicCustomVisuals":["inforiverAppPremium2B7A5FD2992D434DAE0B149479307B7B"]}/g' "${LAYOUT_FILE}.utf8" | |
| # Convert back to UTF-16LE | |
| print_info " - Converting Layout back to UTF-16LE..." | |
| iconv -f UTF-8 -t UTF-16LE "${LAYOUT_FILE}.utf8" > "$LAYOUT_FILE" | |
| rm "${LAYOUT_FILE}.utf8" | |
| print_info "Layout file modified successfully" | |
| else | |
| print_error "Layout file not found at $LAYOUT_FILE" | |
| exit 1 | |
| fi | |
| # Step 6: Zip the files and rename as pbix | |
| print_info "Step 6: Creating new PBIX file..." | |
| # Remove old output file if it exists | |
| [ -f "$OUTPUT_FILE" ] && rm "$OUTPUT_FILE" | |
| # Create PBIX using Python to ensure Windows-compatible ZIP format | |
| # PBIX files require DOS/FAT-style ZIP format for compatibility | |
| OUTPUT_PATH="$OLDPWD/$OUTPUT_FILE" | |
| python3 - "$OUTPUT_PATH" <<'PYTHON_SCRIPT' | |
| import os | |
| import zipfile | |
| import sys | |
| def create_pbix_zip(source_dir, output_file): | |
| """Create a Windows-compatible ZIP file for PBIX""" | |
| # Create list of files first to avoid including the output in the walk | |
| files_to_add = [] | |
| for root, dirs, files in os.walk(source_dir): | |
| for file in files: | |
| if file.endswith('.backup') or file == '.DS_Store': | |
| continue | |
| file_path = os.path.join(root, file) | |
| arcname = os.path.relpath(file_path, source_dir) | |
| files_to_add.append((file_path, arcname)) | |
| # Now create the ZIP with DOS/Windows format | |
| with zipfile.ZipFile(output_file, 'w', zipfile.ZIP_DEFLATED) as zipf: | |
| for file_path, arcname in files_to_add: | |
| # Create ZipInfo to control the file attributes | |
| zinfo = zipfile.ZipInfo(filename=arcname) | |
| zinfo.compress_type = zipfile.ZIP_DEFLATED | |
| # Get file stats | |
| st = os.stat(file_path) | |
| zinfo.external_attr = 0o644 << 16 # Unix permissions, but we'll set create_system | |
| zinfo.create_system = 0 # 0 = MS-DOS/Windows, 3 = Unix | |
| # Set the date_time from the file | |
| from time import localtime | |
| zinfo.date_time = localtime(st.st_mtime)[:6] | |
| with open(file_path, 'rb') as f: | |
| zipf.writestr(zinfo, f.read()) | |
| output_file = sys.argv[1] | |
| create_pbix_zip('.', output_file) | |
| PYTHON_SCRIPT | |
| cd "$OLDPWD" | |
| print_info "${GREEN}✓${NC} Conversion completed successfully!" | |
| print_info "Output file: $OUTPUT_FILE" | |
| # Show summary | |
| echo "" | |
| echo "Summary of changes:" | |
| echo " - SecurityBindings file removed (if present)" | |
| echo " - pivotTable visuals → inforiverAppPremium" | |
| echo " - tableEx visuals → inforiverAppPremium" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment