I am trying to edit the XML stream of Powerpoint slides using OpenXml and Streamreader/Streamwriter.
For a word document, it's easy:
Imports System.IO
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Presentation
Imports DocumentFormat.OpenXml.Wordprocessing
'
'
'
' Open a word document
CurrentOpenDocument = WordprocessingDocument.Open(TheWordFileName, True)
' for a word document, this works
Using (CurrentOpenDocument)
' read the xml stream
Dim sr As StreamReader = New StreamReader(CurrentOpenDocument.MainDocumentPart.GetStream)
docText = sr.ReadToEnd
' do the substitutions here
docText = DoSubstitutions(docText)
' write the modified xml stream
Dim sw As StreamWriter = New StreamWriter(CurrentOpenDocument.MainDocumentPart.GetStream(FileMode.Create))
Using (sw)
sw.Write(docText)
End Using
End Using
But for Powerpoint (presentations), I find that the inserted modified XML stream for the slideparts do not get saved:
Imports System.IO
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Presentation
Imports DocumentFormat.OpenXml.Wordprocessing
'
'
' Open a powerpoint presentation
CurrentOpenPresentation = PresentationDocument.Open(ThePowerpointFileName, True)
' for a powerpoint presentation, this doesn't work
Using (CurrentOpenPresentation)
' Get the presentation part of the presentation document.
Dim pPart As PresentationPart = CurrentOpenPresentation.PresentationPart
' Verify that the presentation part and presentation exist.
If pPart IsNot Nothing AndAlso pPart.Presentation IsNot Nothing Then
' Get the Presentation object from the presentation part.
Dim pres As Presentation = pPart.Presentation
' Verify that the slide ID list exists.
If pres.SlideIdList IsNot Nothing Then
' Get the collection of slide IDs from the slide ID list.
Dim slideIds = pres.SlideIdList.ChildElements
' loop through each slide
For Each sID In slideIds
Dim slidePartRelationshipId As String = (TryCast(sID, SlideId)).RelationshipId
Dim TheslidePart As SlidePart = CType(pPart.GetPartById(slidePartRelationshipId), SlidePart)
' If the slide exists...
If TheslidePart.Slide IsNot Nothing Then
Dim sr As StreamReader = New StreamReader(TheslidePart.GetStream)
Using (sr)
docText = sr.ReadToEnd
End Using
docText = DoSubstitutions(docText)
Dim sw As StreamWriter = New StreamWriter(TheslidePart.GetStream(FileMode.Create))
Using (sw)
sw.Write(docText)
End Using
End If
Next
End If
End Using
I've also tried iterating through the in-memory slideparts to check the XML stream, and they ARE changed.
It's just that this never gets saved back to the file in the dispose (end using) and no error exceptions are raised.
Has anyone else experienced this?
After about a week of messing around with this, I came upon the answer. It is to reference the slideparts from the collection instead of referencing via the relationship Id's, although I don't know why this works and the initial approach doesn't:
' This DOES work
Using (CurrentOpenPresentation)
' Get the presentation part of the presentation document.
Dim pPart As PresentationPart = CurrentOpenPresentation.PresentationPart
' Verify that the presentation part and presentation exist.
If pPart IsNot Nothing AndAlso pPart.Presentation IsNot Nothing Then
' reference each slide in turn and do the Substitution
For Each s In pPart.SlideParts
Dim sr As StreamReader = New StreamReader(s.GetStream)
Using (sr)
docText = sr.ReadToEnd
End Using
docText = DoSubstitutions(docText)
Dim sw As StreamWriter = New StreamWriter(s.GetStream(FileMode.Create))
Using (sw)
sw.Write(docText)
End Using
Next
End If
End Using
Related
I am a student in computer science and for a project I need to be able to read from a text file in a way that each line is assigned to a space within an array. This should happen so that each line of text file is read in the order that it appears in the text file. I would also appreciate any methods of writing to a text file as well.
If this question is already explained, could you please direct me to the existing answer.
Things to note:
1) I am coding in a console application in VB.NET
2) I am relatively new at coding
You can do it like this:
Dim sFile As String = "D:\File.txt"
Dim aLines As String() = System.IO.File.ReadAllLines(sFile)
System.IO.File.WriteAllLines(sFile, aLines)
Here's a sample from the official documentation:
Imports System.IO
Public Class Test
Public Shared Sub Main()
Dim path As String = "c:\temp\MyTest.txt"
Dim sw As StreamWriter
' This text is added only once to the file.
If File.Exists(path) = False Then
' Create a file to write to.
Dim createText() As String = {"Hello", "And", "Welcome"}
File.WriteAllLines(path, createText)
End If
' This text is always added, making the file longer over time
' if it is not deleted.
Dim appendText As String = "This is extra text" + Environment.NewLine
File.AppendAllText(path, appendText)
' Open the file to read from.
Dim readText() As String = File.ReadAllLines(path)
Dim s As String
For Each s In readText
Console.WriteLine(s)
Next
End Sub
End Class
Remarks
This method opens a file, reads each line of the file, then adds each line as an element of a string array. It then closes the file. A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. The resulting string does not contain the terminating carriage return and/or line feed.
Module Module1
Sub Main()
'Declare four variables
Dim oReader As New System.IO.StreamReader(".\archive01.txt") 'This file has to exist in the aplication current directory.
Dim oWriter As New System.IO.StreamWriter(".\archive02.txt") 'This file will be created by the software.
Dim oArray() As String = {}
Dim oString As String = Nothing
'For reading from .\archive01.txt and to load in oArray().
oString = oReader.ReadLine
While Not oString Is Nothing
If UBound(oArray) = -1 Then 'Ubound = Upper Bound, also exist LBound = Lower Bound.
ReDim oArray(UBound(oArray) + 1)
Else
ReDim Preserve oArray(UBound(oArray) + 1)
End If
oArray(UBound(oArray)) = New String(oString)
oString = oReader.ReadLine
End While
oReader.Close()
'For writing from oArray() to .\archive02.txt.
For i = 0 To oArray.Count - 1 Step 1
oWriter.WriteLine(oArray(i))
Next
oWriter.Close()
End Sub
End Module
Hi, try with this code. It works well. I hope that this helps to you to learn how to do this kind of things. Thank you very much. And happy codding!. :)
I use my application to fill and print out forms.
When the form is printed out all the text except the name of the customer is stretch black...
I have tried to print the saved PDF and the same result is happening.
When i open the filled out pdf and change the text, the file is printed out correctly..
The code i'm using to fill out the PDF and printing it is under... Is there something that i can change in my code so this dont happens?
Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
Me.xmltopdf()
Me.Print()
End Sub
Private Sub xmltopdf()
Dim pdfTemp As String = My.Settings.SavePDFT ' ---> It's the original pdf form you want to fill
Dim newFile As String = My.Settings.SavePDFS & Me.TextBox1.Text & ".PDF" ' ---> It will generate new pdf that you have filled from your program
' ------ READING -------
Dim pdfReader As New PdfReader(pdfTemp)
' ------ WRITING -------
' If you don’t specify version and append flag (last 2 params) in below line then you may receive “Extended Features” error when you open generated PDF
Dim pdfStamper As New PdfStamper(pdfReader, New FileStream(newFile, FileMode.Create), "\6c", True)
Dim pdfFormFields As AcroFields = pdfStamper.AcroFields
' ------ SET YOUR FORM FIELDS ------
pdfFormFields.SetField("Field_1", TextBox1.Text)
pdfFormFields.SetField("Field_2", TextBox2.Text)
' There is more fields.. just removed them this.
pdfStamper.FormFlattening = False
' close the pdf
pdfStamper.Close()
' pdfReader.close() ---> DON"T EVER CLOSE READER IF YOU'RE GENERATING LOTS OF PDF FILES IN LOOP
End Sub
' Print PDF
Private Sub Print()
' Wait a bit so the PDF file is created before printing.
Threading.Thread.Sleep(2500)
Dim psi As New ProcessStartInfo
psi.UseShellExecute = True
psi.Verb = "print"
psi.WindowStyle = ProcessWindowStyle.Hidden
'psi.Arguments = PrintDialog1.PrinterSettings.PrinterName.ToString()
psi.FileName = My.Settings.SavePDFS & Me.Ordre_NummerTextBox.Text & ".PDF" ' Here specify a document to be printed
Process.Start(psi)
End Sub
This is the printet out PDF.
I made a new PDF File and have had no problems with it sinse.
The old PDF file was 25.8 MB large and the new one is only 140 kB.
Also i remember that the Old file is copied and change several times in the past.
This question already has answers here:
Cannot bind to the target method when creating delegates for properties
(2 answers)
Closed 4 years ago.
I have been researching this for a while, but cant seem to make it work...
have a large sql table (many columns,rows) I must get values for into excel, I am using LINQ to SQL to get each row and using Reflection to iterate each column by name and write it to appropriate excel column. having seen that reflection is slow, I attempted to assign delegates to each property and map it (via dictionary) to the column name to avoid the overhead.
The Question:
In VB.NET when I try assigning a delegate to the GetMethod of the property (say an integer) like this:
Dim prop = GetType(TestSQLClass).GetProperty("SomeColumn")
Dim del As [Delegate] = [Delegate].CreateDelegate(GetType(Func(Of Integer)), prop.GetMethod)
I receive this error:
Cannot bind to the target method because its signature or security
transparency is not compatible with that of the delegate type.
What am I missing?
Thank you for your question. I thought it would be good to have an anwere and found one in C#. Please see the attributions at the bottom of the Module. I liked the idea of a DataType Extension. It even shows up in intellisense. Approximately 1500 records with 10 columns, mostly text, finishes in 3 seconds.
Imports Microsoft.Office.Interop
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Module DataTableToExcel
' Export DataTable into an excel file with field names in the header line
' - Save excel file without ever making it visible if filepath Is given
' - Don't save excel file, just make it visible if no filepath is given
Private excelApp As Excel.Application
Private workSheet As Excel.Worksheet
<Extension>
Public Sub ExportToExcel(tbl As DataTable, excelFilePath As String)
Dim sw As New Stopwatch
sw.Start()
Try
If IsNothing(tbl) OrElse tbl.Columns.Count = 0 Then
Throw New Exception("ExportToExcel: Null or empty input table!")
End If
' load excel, And create a New workbook
excelApp = New Excel.Application()
excelApp.Workbooks.Add()
' single worksheet
workSheet = CType(excelApp.ActiveSheet, Excel.Worksheet)
' column headings
For i = 0 To tbl.Columns.Count - 1
workSheet.Cells(1, i + 1) = tbl.Columns(i).ColumnName
Next
Dim CellArray(tbl.Rows.Count - 1, tbl.Columns.Count - 1) As Object
'rows
For i = 0 To tbl.Rows.Count - 1
'to do: Format DateTime values before printing
For j = 0 To tbl.Columns.Count - 1
CellArray(i, j) = tbl.Rows(i)(j)
Next
Next
workSheet.Range((workSheet.Cells(2, 1)), (workSheet.Cells(tbl.Rows.Count + 1, tbl.Columns.Count))).Value = CellArray
' check file path
If Not String.IsNullOrEmpty(excelFilePath) Then
Try
excelApp.DisplayAlerts = False
workSheet.SaveAs(excelFilePath)
MessageBox.Show("Excel file saved!")
Catch ex As Exception
Throw New Exception("ExportToExcel: Excel file could not be saved! Check filepath." & ex.Message)
End Try
Else ' no file path Is given
excelApp.Visible = True
End If
Catch ex As Exception
Throw New Exception("ExportToExcel:" & ex.Message)
Finally
excelApp.Workbooks.Close()
excelApp.Quit()
Marshal.ReleaseComObject(workSheet)
Marshal.ReleaseComObject(excelApp.Workbooks)
Marshal.ReleaseComObject(excelApp)
End Try
sw.Stop()
Debug.Print(sw.ElapsedMilliseconds.ToString)
End Sub
'contributed by tuncalik; https://stackoverflow.com/questions/8207869/how-to-export-datatable-to-excel
'speed improvement by Tomasz Wiśniewski
'Releasing objects provided by GrammatonCleric
End Module
Imports System.Data.SqlClient
Public Class TestDataTableToExcel
Private dt As New DataTable
Private Sub btnCreateExcelFile_Click(sender As Object, e As EventArgs) Handles btnCreateExcelFile.Click
dt.ExportToExcel("Coffee.xlsx")
End Sub
Private Sub btnCreateDataTable_Click(sender As Object, e As EventArgs) Handles btnCreateDataTable.Click
Using cn As New SqlConnection(My.Settings.CoffeeConnectionString)
Using cmd As New SqlCommand("Select * From Coffees;", cn)
cn.Open()
Using dr As SqlDataReader = cmd.ExecuteReader
dt.Load(dr)
End Using
End Using
End Using
End Sub
End Class
How can I put the text from a TextBox on captured images ?
Is it possible to implement it to code from:
Vb app code
You can easily do it using Bytescout.Watermarking SDK for .NET
Here's an example of code `Imports System.Diagnostics
Imports Bytescout.Watermarking
Imports Bytescout.Watermarking.Presets
Module Module1
Sub Main()
' Create new watermarker
Dim waterMarker As New Watermarker()
' Create new preset
Dim preset As New TextFitsPage()
' Create new string
Dim inputFilePath As String
' Create new string
Dim outputFilePath As String
' Set input file path
inputFilePath = "my_sample_image.jpg" '<-- place your captured image here
' Set output file path
outputFilePath = "my_sample_output.jpg"
' Initialize library
waterMarker.InitLibrary("demo", "demo")
' Add image to apply watermarks to
waterMarker.AddInputFile(inputFilePath, outputFilePath)
' Set preset text
preset.Text = "Bytescout Watermarking" '<-- place your textbox.text here
' Add watermark to watermarker
waterMarker.AddWatermark(preset)
' Set output directory
waterMarker.OutputOptions.OutputDirectory = "."
' Apply watermarks
waterMarker.Execute()
' Open generated image file in default image viewer installed in Windows
Process.Start(outputFilePath)
End Sub
End Module`
Source: how to add a simple transparent watermark
I am using an ajaxfileupload control to upload a pdf file to the server. On the server side, I'd like to convert the pdf to jpg. Using the PDFsharp Sample: Export Images as a guide, I've got the following:
Imports System
Imports System.Drawing
Imports System.Drawing.Imaging
Imports PdfSharp.Pdf
Imports System.IO
Imports PdfSharp.Pdf.IO
Imports PdfSharp.Pdf.Advanced
Namespace Tools
Public Module ConvertImage
Public Sub pdf2JPG(pdfFile As String, jpgFile As String)
pdfFile = System.Web.HttpContext.Current.Request.PhysicalApplicationPath & "upload\" & pdfFile
Dim document As PdfSharp.Pdf.PdfDocument = PdfReader.Open(pdfFile)
Dim imageCount As Integer = 0
' Iterate pages
For Each page As PdfPage In document.Pages
' Get resources dictionary
Dim resources As PdfDictionary = page.Elements.GetDictionary("/Resources")
If resources IsNot Nothing Then
' Get external objects dictionary
Dim xObjects As PdfDictionary = resources.Elements.GetDictionary("/XObject")
If xObjects IsNot Nothing Then
Dim items As ICollection(Of PdfItem) = xObjects.Elements.Values
' Iterate references to external objects
For Each item As PdfItem In items
Dim reference As PdfReference = TryCast(item, PdfReference)
If reference IsNot Nothing Then
Dim xObject As PdfDictionary = TryCast(reference.Value, PdfDictionary)
' Is external object an image?
If xObject IsNot Nothing AndAlso xObject.Elements.GetString("/Subtype") = "/Image" Then
ExportImage(xObject, imageCount)
End If
End If
Next
End If
End If
Next
End Sub
Private Sub ExportImage(image As PdfDictionary, ByRef count As Integer)
Dim filter As String = image.Elements.GetName("/Filter")
Select Case filter
Case "/DCTDecode"
ExportJpegImage(image, count)
Exit Select
Case "/FlateDecode"
ExportAsPngImage(image, count)
Exit Select
End Select
End Sub
Private Sub ExportJpegImage(image As PdfDictionary, ByRef count As Integer)
' Fortunately JPEG has native support in PDF and exporting an image is just writing the stream to a file.
Dim stream As Byte() = image.Stream.Value
Dim fs As New FileStream([String].Format("Image{0}.jpeg", System.Math.Max(System.Threading.Interlocked.Increment(count), count - 1)), FileMode.Create, FileAccess.Write)
Dim bw As New BinaryWriter(fs)
bw.Write(stream)
bw.Close()
End Sub
Private Sub ExportAsPngImage(image As PdfDictionary, ByRef count As Integer)
Dim width As Integer = image.Elements.GetInteger(PdfImage.Keys.Width)
Dim height As Integer = image.Elements.GetInteger(PdfImage.Keys.Height)
Dim bitsPerComponent As Integer = image.Elements.GetInteger(PdfImage.Keys.BitsPerComponent)
' TODO: You can put the code here that converts vom PDF internal image format to a Windows bitmap
' and use GDI+ to save it in PNG format.
' It is the work of a day or two for the most important formats. Take a look at the file
' PdfSharp.Pdf.Advanced/PdfImage.cs to see how we create the PDF image formats.
' We don't need that feature at the moment and therefore will not implement it.
' If you write the code for exporting images I would be pleased to publish it in a future release
' of PDFsharp.
End Sub
End Module
End Namespace
As I debug, it blows up on Dim filter As String = image.Elements.GetName("/Filter") in ExportImage. The message is:
Unhandled exception at line 336, column 21 in ~:46138/ScriptResource.axd?d=LGq0ri4wlMGBKd-1vxLjtxNH_pd26HaruaEG_1eWx-epwPmhNKVpO8IpfHoIHzVj2Arxn5804quRprX3HtHb0OmkZFRocFIG-7a-SJYT_EwYUd--x9AHktpraSBgoZk4VJ1RMtFNwl1mULDLid5o5U9iBcuDi4EQpbpswgBn_oI1&t=ffffffffda74082d
0x800a139e - JavaScript runtime error: error raising upload complete event and start new upload
Any thoughts on what the issue might be? It seems an issue with the ajaxfileupload control, but I don't understand why it would be barking here. It's neither here nor there, but I know I'm not using jpgFile yet.
PDFsharp cannot create JPEG Images from PDF pages:
http://pdfsharp.net/wiki/PDFsharpFAQ.ashx#Can_PDFsharp_show_PDF_files_Print_PDF_files_Create_images_from_PDF_files_3
The sample you refer to can extract JPEG Images that are included in PDF files. That's all. The sample does not cover all possible cases.
Long story short: the code you are showing seems unrelated to the error message. And it seems unrelated to your intended goal.