Convert-Csv.psm1
<#
.Synopsis Csv converter. Converts csv files to html, txt, or json. Supports several formatting options. .Description Csv converter. Converts csv files to html, txt, or json. Supports several formatting options. Further information can be found on https://blog.bajiri.com. .Parameter InputFile The csv file to process .Parameter OutputFile The filename to output to. In the case of multiple files, these will be named 0-filename, 1-filename, and so on. .Parameter Read The number of lines to read at a time. Allows faster processing for large files by reading blocks of lines at a time, instead of reading the whole file. Default is 100. .Parameter Mode The conversion mode. Html, txt, or json. .Parameter HeaderStart Signify the row the headers start at. Convert-Csv assumes the first row of the csv is the column headers unless otherwise specified. .Parameter Size Used with the txt mode. Specifies maximum size for output files. Once the file is larger than the maximum size, it will be split. Default is 104857600 bytes. .Parameter Count Used with html mode. Specifies the number of lines to print on one page. Default is 20. .Parameter Help Display a help menu. .Example Convert-Csv -InputFile .\process.csv -OutputFile Process.html -read 100 -mode html -Count 50 .Link http://blog.bajiri.com #> function Convert-Csv{ param($InputFile, [switch]$help, $OutputFile, $read=100, $Size=104857600, $Mode, $Count, $HeaderStart) if($Help){ Help exit } # Count lines in file [int]$LineCount = 0 $CurrentPath = (Get-Location).Path $Reader = New-Object IO.StreamReader "$CurrentPath\$InputFile" While($Reader.ReadLine() -ne $Null){ $LineCount++ } $Reader.Dispose() # Get Headers - Needs to be in a string array to work with ConvertFrom-Csv if($HeaderStart){ $Headers = Get-Content $InputFile -First $HeaderStart | Select-Object -Last 1 }else{ $Headers = Get-Content $InputFile -First 1 } $Headers = Out-String -InputObject $Headers $Headers = $Headers.split(',') # Load File $LoadedCsv = Get-Content $InputFile -ReadCount $Read # Process Csv $ProcessedCsv = @() Foreach($x in $LoadedCsv){ $ProcessedCsv += ConvertFrom-Csv -InputObject $x -Delimiter ',' -Header $Headers } # Begin output processing if($Mode -eq "html"){ ProcessHtml $LineCount $ProcessedCsv $Headers }elseif($Mode -eq "json"){ ProcessJson $LineCount $ProcessedCsv }else{ ProcessTxt $LineCount $ProcessedCsv } } function ProcessTxt($Lines, $ProcessedCsv){ begin{ $Stopwatch = [System.Diagnostics.Stopwatch]::startNew() } process{ # Create an iterator for file renaming $I = 0 # Write to txt file Foreach($x in $ProcessedCsv){ Out-File -InputObject $x -FilePath $OutputFile -Append # Test file size if((Get-Item $OutputFile).length -gt $Size){ Move-Item $OutputFile "$I-$OutputFile" $I++ } } # Rename operating file to keep numbering correct Move-Item $OutputFile "$I-$OutputFile" } end{ $Stopwatch.Stop() Write-Host "File written to"(Get-location).Path -nonewline;Write-host "\$OutputFile" Write-Host "Time Elapsed(seconds):"$Stopwatch.Elapsed.TotalSeconds Write-Host "Processed $Lines lines" } } function ProcessHtml($Lines, $ProcessedCsv, $headers){ begin{ $Stopwatch = [System.Diagnostics.Stopwatch]::startNew() } process{ # Fragment as table # Create directory if(-not (Get-Item -Path "www")){ New-Item -Path "www" -ItemType Directory }else{ # Destroy existing html Get-ChildItem "www" | %{rm $_.FullName} } # Create Site $HTMLStart = @' <!DOCTYPE html> <HTML> <head> <style> #Device {position: absolute; top: 2%; left: 2%; padding: 0px 0px;} #Author { float: left; padding: 0px 100px; } #Device, #Author { display: inline;} #Content { float: center; top: %5; clear:both; text-align:center; position: relative;} a:link { color: #000000;} a:visited { color: #000000;} h1, h5, th { text-align: center; font-family: Segoe UI;} table { margin: auto; font-family: Segoe UI; box-shadow: 10px 10px 5px #888; border: thin ridge grey; } th { background: #0046c3; color: #fff; max-width: 400px; padding: 5px 10px; text-wrap:normal; word-wrap:break-word;} td { font-size: 11px; padding: 5px 20px; color: #000; max-width: 600px; text-wrap:normal; word-wrap:break-word; } tr { background: #b8d1f3; text-wrap:normal; word-wrap:break-word} tr:nth-child(even){ background: #dae5f4; text-wrap:normal; word-wrap:break-word;} p { text-align: center;} .Summary { margin: auto; overflow: hidden;} iframe { margin: auto; width: 1200; height: 400; display:block; border: 0px;} ul { display: inline-block; text-align: left;} .sidenav {height: 100%;width: 0;position: fixed;z-index: 1;top: 0;left: 0;background-color: #111;overflow-x: hidden;transition: 0.5s;padding-top: 60px;} .sidenav a {padding: 8px 8px 8px 32px;text-decoration: none;font-size: 25px;color: #818181;display: block;transition: 0.3s;} .sidenav a:hover {color: #f1f1f1;} .sidenav .closebtn {position: absolute;top: 0;right: 25px;font-size: 36px;margin-left: 50px;} @media screen and (max-height: 450px) {.sidenav {padding-top: 15px;}.sidenav a {font-size: 18px;}} #myInput {position: absolute; transform: translate(500px,40px);} </style> </head> <body> <div id="Content"> <span style="font-size:30px;cursor:pointer;float:left;" onclick="openNav()">☰ Contents</span> <input id='myInput' onkeyup='searchSname()' type='text'> <!--<button id="searchbutton" onclick="findString()">Search</button>--> <h1 id="title"> <script> var fileName = location.href.split("/").slice(-1); var out = String(fileName).split("."); document.getElementById("title").innerHTML = out[0] + " titlehere"; function openNav() { document.getElementById("mySidenav").style.width = "250px"; } function closeNav() { document.getElementById("mySidenav").style.width = "0"; } </script> </h1> <!--credit: https://stackoverflow.com/questions/40873163/searching-text-within-html-table--> <script type="text/javascript"> function searchSname() { var input, filter, found, table, tr, td, i, j, text, head, count; input = document.getElementById("myInput"); filter = input.value.toUpperCase(); table = document.getElementById("myTable"); tr = table.querySelectorAll("tr:not(#header)"); head = table.querySelectorAll("th"); for (i = 0; i < tr.length; i++) { td = tr[i].getElementsByTagName("td"); for (j = 0; j < td.length; j++) { text = filter.split("="); if (head[j].innerText.toUpperCase().indexOf(text[0]) > -1 && td[j].innerText.toUpperCase().indexOf(text[1]) > -1) { found = true; count = j; } } if (found) { tr[i].style.display = ""; found = false; } else { tr[i].style.display = "none"; } } } </script> <div id="mySidenav" class="sidenav"> <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a> '@ # Process into html tables # Get count if(!$count){ # If count is not specified,print all objects to html page $count=$Lines } $a = 0 $Base = $Count for($I=0;$Count -le $Lines;$I++){ ([regex]'<tr>').replace(($ProcessedCsv | Select -Index ($a..$Count) | ConvertTo-Html -Fragment).replace("<table>","<table id='myTable'>"),"<tr id='header'>",1) | Out-File -FilePath "www\$I-$OutputFile" # Add link to the nav menu for eah file $NavAdd =@' <a href="{0}">Page {1}</a> '@ -f "$I-$OutputFile", $I $HTMLStart += $NavAdd $a = $count + 1 $Count = $Count + $Base } # End HTML $HTMLEnd=@' </body> </html> '@ # Add html header into all html files in www Foreach($x in Get-ChildItem www){ $Current = Get-Content -Path www\$x Out-File -InputObject ($HTMLStart).replace("titlehere","lines: $lines") -FilePath www\$x Add-Content -Value "`t`t`t</div>`n" -Path www\$x Add-Content -Value $Current -Path www\$x Add-Content -Value $HTMLEnd -Path www\$x } } end{ $Stopwatch.Stop() Write-Host "Files written to www: " (Get-ChildItem www).count Write-Host "Time Elapsed(seconds):"$Stopwatch.Elapsed.TotalSeconds Write-Host "Processed $Lines lines" } } function ProcessJson($Lines, $ProcessedCsv){ begin{ $Stopwatch = [System.Diagnostics.Stopwatch]::startNew() } process{ Out-File -FilePath $OutputFile -InputObject (ConvertTo-Json -InputObject $ProcessedCsv) } end{ $Stopwatch.Stop() Write-Host "File written to"(Get-location).Path -nonewline;Write-host "\$OutputFile" Write-Host "Time Elapsed(seconds):"$Stopwatch.Elapsed.TotalSeconds Write-Host "Processed $Lines lines" } } function Help{ write-host "`nConvert-Csv converts csv files into text, html, or json files." write-Host "`nGeneral Parameters" Write-Host "`t-Inputfile`n`t`tThe csv to process." Write-Host "`t-OutputFile`n`t`tThe name, including extension, of the file to be written.`n`t`tIn the case of multiple output files, they will be name 0-filename, 1-filename, etc..." Write-Host "`t-Read`n`t`tThe amount of lines to read at one time from the csv. Useful for large csv files.`n`t`tDefault = 100." Write-Host "`t-Mode`n`t`tThe desired output type. Html, Txt, or Json." Write-Host "`nText Mode:" Write-Host "`t-Size`n`t`tThe maximum size, in bytes, of the output text files." Write-Host "`nHtml Mode:" Write-Host "`t-Count`n`t`tThe number of lines to print on each page.`n`t`tDefault = 20" Write-Host "`nExample: .\Convert-Csv.ps1 -InputFile .\process.csv -OutputFile Process.html -read 100 -mode html -Count 50" } Export-ModuleMember -Function Convert-Csv |