Itextsharp fit width and give border - vb.net

I am designing a table in pdf using itextsharp. I want to ask if anyone knows:
How to give border (like color = silver, 1px, fit to width) to
header text?
How to make table fit to page width (like 100%)?
I am using vb.net
Protected Sub Create_Pdf_Click(sender As Object, e As EventArgs) Handles Create_Pdf.Click
Dim pdfDoc As New Document()
Dim pdfWrite As PdfWriter = PdfWriter.GetInstance(pdfDoc, New FileStream("D://PDF/myfile.pdf", FileMode.Create))
pdfDoc.Open()
pdfDoc.Add(New Paragraph("Here is header text"))
Dim table As New PdfPTable(3)
Dim cell As New PdfPCell(New Phrase("Header spanning 3 columns"))
cell.Colspan = 3
cell.HorizontalAlignment = 1
table.AddCell(cell)
table.AddCell("Col 1 Row 1")
table.AddCell("Col 2 Row 1")
table.AddCell("Col 3 Row 1")
table.AddCell("Col 1 Row 2")
table.AddCell("Col 2 Row 2")
table.AddCell("Col 3 Row 2")
pdfDoc.Add(table)
pdfDoc.Close()
End Sub

When you define a Document like this:
Dim pdfDoc As New Document()
You define a document with pages of size A4 and margins of 36 user units. If you don't want any margins, you need to create your document like this:
Document doc = new Document(PageSize.A4, 0f, 0f, 0f, 0f);
When you create your PdfPTable like this:
Dim table As New PdfPTable(3)
You create a table that takes 80% of the available width. You can change this to 100% by adding this line:
table.WidthPercentage = 100
Or, if you want to specify a specific width, then you can use:
table.TotalWidth = 595f
table.LockedWidth = true
Note that 595 is the width (in user units) of an A4 page.
Borders are defined at the level of a PdfPCell:
PdfPCell cell = new PdfPCell(phrase)
cell.BorderColor = BaseColor.RED
cell.BorderWidth = 3f
cell.Border = Rectangle.BOX
Of course, you can also define each border separately. That is explained here: ITextSharp: Set table cell border color
In your case, you may want to define these properties for the DefaultCell. This way, you don't have to define them over and over again for each separate cell.
It would lead us too far if I would go into more detail (e.g. I could also talk about table events and cell events, for instance to draw dashed borders). Please download the free ebook The Best iText Questions on StackOverflow where you will find the answers to some questions that are even less trivial than yours.

Related

Create ImageBox in Microsoft Word document and insert image with Visual Basic

I'm working on a project in VB which has to do with document processing in Microsoft Word. I have difficulty on creating an ImageBox with certain size in a the document. Does anybody have an idea on how to do this? Can it even be done? The goal is to create the ImageBox and then insert an image to this box. The image must stretch and get the size of the ImageBox.
What I've done until now is this:
(...)
Dim NewSize As Size
NewSize = New Size(Width, Height)
ResizedImage = New Bitmap(ImageToInsert, NewSize)
(...)
WordDocument.AddPicture(DirectoryAddress & "\ResizedImage." & ImageExtension)
Though, what this code does, is to insert an image with specified size in the Word document. What I want is, the image to stretch and get the size of the ImageBox that will have been created. I hope I was clear enough.
Thanks in advance!
Well, if you were to look at the properties of the table you're creating, you would see that you have not created a table with a fixed height and width. To do that, you could use something like:
NewTable = WordDoc.Tables.Add(para.Range, 1, 1, 0, 0)
NewTable.Cell(1,1).Width(500)
NewTable.Cell(1,1).Height(389)
NewTable.Cell(1, 1).HeightRule(2)
or, in VBA:
Set NewTable = WordDoc.Tables.Add(para.Range, 1, 1, 0, 0)
NewTable.Cell(1,1).Width = 500
NewTable.Cell(1,1).Height = 389
NewTable.Cell(1, 1).HeightRule = 2
Thanks to #CindyMeister and #macropod I managed to create what I needed. So here is the answer:
Dim rng As Word.Range
(...)
rng = para.Range
(...)
Dim img As Image = Image.FromFile(imagePath)
Dim objtable as Word.Table
'In my case I needed a temporary paragraph to be added for my project and later delete it. If you don't need it, just don't declare it.
Dim tempTablePara As Word.Paragraph = WordDoc.Content.Paragraphs.Add() 'Previously declared WordDoc as Word.Document
objtable = WordDoc.Tables.Add(rng, 1, 1)
objtable.Cell(1, 1).Width = img.Width * 0.75 'width is in pixels, convert to points
objtable.Cell(1, 1).Height = img.Height* 0.75 'height is in pixels, convert to points
objtable.Cell(1, 1).HeightRule = Word.WdRowHeightRule.wdRowHeightExactly ' Done so as the cell to get the same size with the picture
Dim objShapes = objtable.Range.InlineShapes
rng = tempTablePara.Range
tempTablePara.Range.Delete()
objShapes.AddPicture(imagePath)
'add cell borders
With objtable.Rows(1).Cells.Borders
.InsideLineStyle = Word.WdLineStyle.wdLineStyleSingle
.OutsideLineStyle = Word.WdLineStyle.wdLineStyleSingle
End With
Extra. What I was looking for, was to insert an image to an already designed frame in a word document. So for me the pre-designed frame was a one cell table. If you just want to add a frame around a picture then the following code should work just fine.
Dim shape
(...)
shape = WordDoc.InlineShapes.AddPicture(imagePath, Type.Missing, Type.Missing, rng)
rng = shape.Range
Dim objshape As Word.InlineShape
objshape = shape
objshape.Borders.OutsideLineStyle = Word.WdLineStyle.wdLineStyleSingleWavy
objshape.Borders.OutsideColor = Word.WdColor.wdColorBlack
rng.Collapse(Word.WdCollapseDirection.wdCollapseEnd)

iTextsharp - draw a line at the end and start of a page with tables

Selecting records from a table I create iTextsharp's Tables one for every first letter of the records
On the picture a table for the "G" letter:
"G" is a row of 6 cells
Then a row of 6 cells with the "headers"
and then rows with records
The cells of the rows only need left and right border.
But I need to draw or "close" the line for the last row of the page and also draw or "open" the line of the first row of the next page.
I read a lot of post but I can't figure it out the solution
I know how to draw a graphic line and how to find the coords or how to set bottom or top border, but I don´t know how to detect the page break or if I can manage this situation with forced footers or headers only on cases like the one of the picture.
The code of the class adapated to VB
Thanks to COeDev for the support
Now I only need to resolve the Rectangle (or draw a line) because is not the same on VB.NET (Lines marked as comment)
Imports iTextSharp.text.pdf
Public Class LineaBottom
Implements IPdfPTableEvent
Public Sub TableLayout(table As PdfPTable, widths As Single()(), heights() As Single, headerRows As Integer, rowStart As Integer, canvases() As PdfContentByte) Implements IPdfPTableEvent.TableLayout
'Throw New NotImplementedException()
Dim columns As Integer
Dim rect As Rectangle
Dim footer As Integer = widths.Length - table.FooterRows
Dim header As Integer = table.HeaderRows - table.FooterRows + 1
Dim ultima As Integer = footer - 1
If ultima <> -1 Then
columns = widths(ultima).Length - 1
rect = New Rectangle(widths(ultima)(0), heights(ultima), widths(footer - 1)(columns), heights(ultima + 1))
'rect.BorderColor = BaseColor.BLACK
'rect.BorderWidth = 1
'rect.Border = Rectangle.TOP_BORDER
'canvases(PdfPTable.BASECANVAS).Rectangle(rect)
End If
End Sub
I hope this code will serve other people because there is not much information on the Internet
This should be helpful for you: itextsharp: how to show the bottom line of a table with property HeaderRows=1 if border bottom of the row is not set?
You will need to add some code to draw an additional header line, too
e.g.:
columns = widths[0].Length - 1;
rect = new Rectangle(widths[0][0], heights[0], widths[0][columns], heights[0]);
rect.BorderColor = Color.BLACK;
rect.BorderWidth = 1;
rect.Border = Rectangle.TOP_BORDER;
canvases[PdfPTable.BASECANVAS].Rectangle(rect);
4.1.6.0
I found the solution, no new class required
Dim heightActualLetter, verticalSpaceAvailable As Integer
heightActualLetter = table.TotalHeight
verticalSpaceAvailable = pdfWrite.GetVerticalPosition(False) - pdfDoc.BottomMargin
If heightActualLetter > verticalSpaceAvailable Then
Dim finalLine As PdfContentByte
finalLine = pdfWrite.DirectContent
Dim curY As Int32
curY = pdfWrite.GetVerticalPosition(False)
finalLine.SetLineWidth(0.5)
finalLine.MoveTo(xStart, curY)
finalLine.LineTo(xEnd + 1, curY)
finalLine.Stroke()
End If
I don´t know why I need the +1 on xEnd + 1 but maybe is because of the other lines being 0.5 I need to rounded up

itextsharp add text above of chunk image

I want to get some text in above of my image. my code like this :
Dim pdfcb As PdfContentByte = Writer.DirectContent
Dim code128 As New Barcode128()
code128.Code = partnumber
code128.Extended = False
code128.CodeType = iTextSharp.text.pdf.Barcode.CODE128
code128.AltText = ""
code128.BarHeight = 13
code128.Size = 6
code128.Baseline = 8
code128.TextAlignment = Element.ALIGN_CENTER
Dim image128 As iTextSharp.text.Image = code128.CreateImageWithBarcode(pdfcb, Nothing, Nothing)
Dim phrase As New Phrase()
phrase.Font.Size = 10
Dim cell As New PdfPCell(phrase)
cell.FixedHeight = 68.69F
cell.HorizontalAlignment = Element.ALIGN_CENTER
cell.VerticalAlignment = Element.ALIGN_MIDDLE
cell.Border = iTextSharp.text.Rectangle.NO_BORDER
phrase.Add(New Chunk(Environment.NewLine + "Companyname"))
phrase.Add(New Chunk(Environment.NewLine + "address"))
phrase.Add(New Chunk(image128, 10, 30))
phrase.Add(New Chunk(Environment.NewLine + partnumber))
phrase.Add(New Chunk(Environment.NewLine + "111"))
tbl.AddCell(cell)
I am always getting my address and company name below of my image.
i want to make that in above of my image
What i can do for that? any help is very appreciable.
You are using PdfPCell in text mode. You shouldn't do that if you want to add an Image. Use PdfPCell in composite mode instead:
Dim cell As New PdfPCell(phrase)
cell.FixedHeight = 68.69F
cell.VerticalAlignment = Element.ALIGN_MIDDLE
cell.AddElement(New Paragraph("CompanyName"))
cell.AddElement(New Paragraph("Address"))
cell.AddElement(image128)
cell.AddElement(New Paragraph(partnumber))
cell.AddElement(New Paragraph("11"))
tbl.AddCell(cell)
Note that I removed the following line:
cell.HorizontalAlignment = Element.ALIGN_CENTER
In composite mode, you need to change the alignment of the elements that you're adding. In this case: you need to change the aligment of the Paragraph objects (that's fairly easy to accomplish). See Alignment, indentation, leading and spacing in cells, How to use multiple fonts in a single cell? and How to right-align text in a PdfPCell?
Your question is also an almost exact duplicate of the question How to put text above a bar code instead of under the bars? which was posted on StackOverflow on January 26, 2016 (little over a month ago).

Tablelayout panel rowstyle

I have a table layout panel that I am dynamically adding rows to using the following code:
attemptstlp.RowCount += 2
attemptstlp.Height = attemptstlp.Height + 62
attemptstlp.RowStyles.Add(New RowStyle(SizeType.Absolute, 30))
(just so you know attemptstlp is the name of the panel)
I am using a loop to process through these rows adding them. I am finding that all is working except half way through the row style stops applying (so if i want to add 24 lots of 2 rows the height will stop applying after the 12th lot of rows has been added).
Could anyone offer suggestions on why the rows are reverting (i assume) to auto size after half of them have been added. The only other lines of code that refer to this panel is the lines adding the text boxes and the lines to suspend and resume layout to help reduce the flickering and time taken to load.
The table layout panel has an inital height of 40 with 1 row of height 39 when first created.
Thanks in advance,
mrtechguy
This works perfectly for adding rows and controls in a TableLayoutPanel. Try and see.
'Define a blank Tablelayoutpanel with 3 columns in the design page
Dim TableLayoutPanel3 As New TableLayoutPanel()
TableLayoutPanel3.Name = "TableLayoutPanel3"
TableLayoutPanel3.Location = New System.Drawing.Point(32, 287)
TableLayoutPanel3.AutoSize = True
TableLayoutPanel3.Size = New System.Drawing.Size(620, 20)
TableLayoutPanel3.ColumnCount = 3
TableLayoutPanel3.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single
TableLayoutPanel3.BackColor = System.Drawing.Color.Transparent
TableLayoutPanel3.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 26.34146!))
TableLayoutPanel3.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 73.65854!))
TableLayoutPanel3.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 85.0!))
Controls.Add(TableLayoutPanel3)
'Create a button btnAddRow to add rows on each click
Private Sub btnAddRow_Click(sender As System.Object, e As System.EventArgs) Handles btnAddRow.Click
TableLayoutPanel3.GrowStyle = TableLayoutPanelGrowStyle.AddRows
TableLayoutPanel3.RowStyles.Add(New RowStyle(SizeType.Absolute, 20))
TableLayoutPanel3.SuspendLayout()
TableLayoutPanel3.RowCount += 1
Dim tb1 As New TextBox()
Dim tb2 As New TextBox()
Dim tb3 As New TextBox()
TableLayoutPanel3.Controls.Add(tb1 , 0, TableLayoutPanel3.RowCount - 1)
TableLayoutPanel3.Controls.Add(tb2, 1, TableLayoutPanel3.RowCount - 1)
TableLayoutPanel3.Controls.Add(tb3, 2, TableLayoutPanel3.RowCount - 1)
TableLayoutPanel3.ResumeLayout()
tb1.Focus()
End Sub

One picture box shown many times in the same form

My Goal is to create a maze in VS using VB.net, I currently have managed to make a random Generator that makes the "maze" and shows the location of the last wall made.
Horizontalwalls = Randomizer.Next(60, 91) 'Makes 60 - 90 Horizontal Walls
VirticalWalls = Randomizer.Next(60, 91) 'Makes 60 -90 Vertical Walls
Dim HLoops = 0 'counter for Horizontal walls
Dim VLoops = 0
lbxHorizontal.Items.Clear() 'empties the list box i have which stores the walls location
lbxvertical.Items.Clear()
Do While HLoops < (Horizontalwalls)
HLoops += 1 'adds to the counter
lbxHorizontal.Items.Insert(0, Randomizer.Next(0, 10))
lbxHorizontal.Items.Insert(0, Randomizer.Next(0, 10))
'Attempt at making visable walls
pbxhorizontalwall.Top = (lbxHorizontal.Items.Item(0) * GridSize - 2) 'This and next line puts the wall in desired location
pbxhorizontalwall.Left = (lbxHorizontal.Items.Item(1) * GridSize - 2)
Loop
however the only way i know to make all the walls visible is to make 90 horizontal wall pictures, go though naming them all, then GLaaa... there must be a easier way to copy the same image over the screen at the desired location.
At the moment, all i really want to know is the line of code that will copy the image (and maybe a way to mass clear them all when the maze is reset) and then i'll work out how to get it into place...
You first create the list of images with:
Dim imageList As New List(Of Bitmap)
imageList.Add("image to add") 'do it for all the images you have
Then create a bitmap:
Dim bitmapWall as Bitmap = New Bitmap(widthOfbitmap, heightofbitmap, Drawing.Imaging.PixelFormat.Format24bppRgb)
Draw the list of images to the bimap:
Dim objGraphics As Graphics = Graphics.FromImage(bitmapWall)
For i = 0 To imageList.Count
objGraphics.DrawImage(imageList(i), x, y, imageList(i).Width, imageList(i).Height)
Next
objGraphics.Dispose()
x,y is the coordinates of where your images are drawn (you should change them for every iteration)
Lastly:
Me.BackgroundImage = bitmapWall
Me.Invalidate()
Dont forget to dispose the list and the bitmap in the end.
valter