Do I need nested grids and tables for this?

Hello,

Trying to use the PDF engine. Cannot seem to figure out proper layout.

Grid with "meeting data" at the top.
A collection of diagrams with metadata in multiple rows.

Need to insert images into the grid that are over sized: eg 900x450px
I want to scale these down proportionally to fit half-width of my grid.

It seems the PdfGrid NEEDS the DataTable.
I cannot seem to figure out how to put this together using the PDF engine.
Nested grids? Nested tables?

Title spans two cols. Notes spans two cols
Diagrams are in one col but span 3 rows.
If data requires a second page, I'd like a clean page break, add new page and continue.

I'd also like to NOT display gridlines. 

Are there any more complex project samples that deal with similar arrangement?

I've attached a pdf of what I'm trying to achieve.

I'd rather just create a grid, set col or row spans and fill the cells...
.
Any tips/suggestions?

Thanks

Attachment: Diagram_Review_991e662b.zip

16 Replies

SL Sowmiya Loganathan Syncfusion Team June 1, 2020 12:37 PM UTC

Hi Lindsay,   
  
Thank you for contacting Syncfusion support.   
  
We have analyzed your requirement and we have created the sample based on the expected output. Please find the download link from below,  
  
  
Please find the below documentation link for your reference,   
  

Please try the sample in your end and let us know if you need any further assistance on this.   

Regards,  
Sowmiya Loganathan  




LM Lindsay Miles June 1, 2020 05:26 PM UTC

Excellent, thanks for your help!

Some of the online documentation seems to indicate a datatable is needed and manipulating the grid is not all that clear.
I'm sure this will help progress!

QUESTION: how would one check available page space (based on A4 page size) so that a new page can be added and data continued to that next page?


Thanks again.


SL Sowmiya Loganathan Syncfusion Team June 2, 2020 11:42 AM UTC

Hi Lindsay,   
  
Thank you for the update.   
  
You can able to get the page size and table size by using below code snippet,   
  
Page Size:   
//Get page size  
SizeF pageSize = page.Size 
  
Table Size:   
//Create a PdfGrid  
PdfGrid pdfGrid = new PdfGrid();  
  
//Draw grid to the page of PDF document  
PdfGridLayoutResult result = pdfGrid.Draw(page, new PointF(10, 10));  
  
RectangleF tableSize = result.Bounds;  
  
However, you don’t need to calculate the page size to paginate the table. Because while setting PdfGridLayoutFormat to paginate, it will automatically paginate the grid if it exceeds the page size. Please refer the below documentation link for more details,   
  
Please let us know if you have any concerns on this.   
  
Regards,  
Sowmiya Loganathan  
 



LM Lindsay Miles June 2, 2020 12:20 PM UTC

Excellent! Thanks again for help and feedback!


LM Lindsay Miles June 3, 2020 02:23 PM UTC

Sorry, another question:

If the image I'm inserting is large (2000px width 1000px height) would this scale to fit the cell?
Do I need to scale the image down?

Ideally, I could get the page-grid-width OR the cell-width compared to the actual image width, then scale the image proportionally by that factor.
PdfBitmap does not seem to offer that kind of functionality however.

Any suggestions on doing that?
I could scale the image using SkiaSharp functionlity then insert the scaled image into the grid. Not sure if that'll work...

As-is, the image doesn't even print on the pdf, no error either.

SOLVED - the cell height has to be set to that of the image, scaled.

QUESTION: How does one hide gridlines? Borders?
Doing this hides the images too:
cellStyle.Borders.All = new PdfPen(Syncfusion.Pdf.Graphics.PdfColor.Empty); then apply to all cells.

TRANSPARENT GRID SOLUTION
You cannot set a style for all borders and apply to gridcells as that causes images to not display.
Also, if you apply a global style to all cells then set an image to a particular cell.style, that images appears in all cells.

You need to build the grid with all data THEN loop through rows, then cells, then set each border to whatever you want. That works.



Thanks



SL Sowmiya Loganathan Syncfusion Team June 3, 2020 02:28 PM UTC

Hi Lindsay,   
  
If the image I'm inserting is large (2000px width 1000px height) would this scale to fit the cell?
Do I need to scale the image down? 
 
  
Ideally, I could get the page-grid-width OR the cell-width compared to the actual image width, then scale the image proportionally by that factor.  
PdfBitmap does not seem to offer that kind of functionality however.  
  
Any suggestions on doing that?  
I could scale the image using SkiaSharp functionlity then insert the scaled image into the grid. Not sure if that'll work...  
  
While inserting the image to PdfGridCell, there is no need to scale the image to cell size. Because the image will fit to the cell size while adding it as background. Please refer the below code snippet,   
  
//Creates the PdfGrid  
PdfGrid pdfGrid = new PdfGrid();  
PdfBitmap bitmap = newPdfBitmap(imageStream);  
pdfGrid.Rows[0].Cells[0].Style.BackgroundImage = bitmap;  
  
Or else you can insert the image to grid cell by using BeginCellLayout event handler. Please refer the below code snippet for more details,  
  
pdfGrid.BeginCellLayout += PdfGrid_BeginCellLayout;  
  
  
private static voidPdfGrid_BeginCellLayout(object sender, PdfGridBeginCellLayoutEventArgs args)  
 
    //Draw image in first row of cell 0  
    if (args.RowIndex == 1 && args.CellIndex == 0)  
     
        //Load the image  
        PdfBitmap image1 = newPdfBitmap(imageStream);  
  
        //Draw the image  
        args.Graphics.DrawImage(image1, newRectangleF(args.Bounds.X, args.Bounds.Y, args.Bounds.Width, args.Bounds.Height));     
     
 
  
  
As-is, the image doesn't even print on the pdf, no error either.  
Please provide us the below details to replicate to check this issue in our end and provide the precise solution on this.   
  
  • Sample / code snippet
  • Output document
  • Image file used in your end
  
  
Regards,  
Sowmiya Loganathan  
 



SL Sowmiya Loganathan Syncfusion Team June 9, 2020 01:10 PM UTC

Hi Lindsay,    
   
We have analyzed your requirement and we can able to fix the image (Width – Smaller than a cell, Height – Greater than a cell) in PdfGridCell without expanding its width and height by using below code snippet,    
   
pdfGrid.BeginCellLayout += PdfGrid_BeginCellLayout;   
   
private static voidPdfGrid_BeginCellLayout(object sender, PdfGridBeginCellLayoutEventArgs args)     
{     
    //Draw image in first row of cell 0     
    if (args.RowIndex == 1 && args.CellIndex == 0)     
    {     
        //Load the image     
        PdfBitmap image = new PdfBitmap(imageStream);     
     
        //Draw the image     
        args.Graphics.DrawImage(image1, newRectangleF(args.Bounds.X, args.Bounds.Y,image.Width, args.Bounds.Height));        
    }     
}     
   
Note: If the image size is smaller than the cell size and you don’t want to fit the cell, you can add the image with image size.    
   
If you have to face any issues related to this, kindly provide the image file used in your end. It will helpful for us to provide a precise solution to this.    
  
Regards, 
Sowmiya Loganathan 



LM Lindsay Miles June 10, 2020 02:24 AM UTC

Hello,

Most of this is working really well now.

How do I maintain aspect ratio on all the diagrams?
I find the diagram expands to the width of a cell but is squashed vertically.

Is there a way to fit a diagram to fixed-width cell and have the vertical scale proportionally?

ANY info on this?
How to maintain aspect ratio for an image inserted into a cell?

Thanks


LM Lindsay Miles June 13, 2020 06:52 PM UTC

Hello,

I have the following loop inserting diagrams and data into cells.
This fundamentally works but the height of each image is distorted as it expands or contracts to the row-space it is given

The BeginCellLayout event handler does NOT work for me at all.
It fires AFTER this loop through my data completes.
Images are not inserted into row 1 and cell 0. I'd need to track exactly what row/cell each image is going into AND the images too as each is different.

Images could be 900px width 450px height OR 900 x 900 OR 450 x 450 etc. Each diagram needs to scale proportionately!


                foreach (PlanDiagram pd in plan.PlanDiagrams)
                {
                    string pngPath = Xamarin.Forms.DependencyService.Get().GetDatabasePath();
                    var filePath = Path.Combine(pngPath, pd.Diagram.Id + Constants.FILE_EXTENSION_PNG);
                    var fileStream = new FileStream(filePath, FileMode.Open);
                    PdfBitmap image = new PdfBitmap(fileStream);

                    PdfGridRow r1 = pdfGrid.Rows.Add();

                    //Left Column
                    r1.Cells[0].Style.BackgroundImage = image; //NEED TO SET IMAGE SIZE HERE - proportional, maintain aspect ratio!
                    r1.Cells[0].RowSpan = 2;

NOTE: Image width is not a problem, that scales to cell width. The image height needs to proportionately adjust based on width!

                    //Right Column
                    r1.Cells[1].Value = pd.Diagram.Name;

                    PdfGridRow r2 = pdfGrid.Rows.Add();
                    r2.Cells[1].Value = "Keypoints: " + pd.Diagram.KeyPoints;

                    PdfGridRow r3 = pdfGrid.Rows.Add();
                    r3.Cells[1].Value = "";
                    r3.Height = 10;

                    //if(Settings.IncludeDescriptions)
                    //{

                    //Row3 - Whole Row
                    PdfGridRow rowN = pdfGrid.Rows.Add();
                    rowN.Cells[0].Value = "Description: " + pd.Diagram.Description;
                    rowN.Cells[0].ColumnSpan = 2;

                    //}
                    PdfGridRow row5 = pdfGrid.Rows.Add();
                    row5.Cells[0].Value = "";
                    row5.Height = 10;
                }

Thank you.


SL Sowmiya Loganathan Syncfusion Team June 15, 2020 12:29 PM UTC

Hi Lindsay,   
  
We have analyzed your requirement “Need to change the image size based on the cell width and height”, but we could not able to set the size of the image while adding it as background to the cell. However, as a workaround we can able to resize the image with specified width and height (based on the cell size). Please refer the below code snippet for more details,   
  
private static void ReduceImageSize(System.Drawing.Image image, string destinationPath,int percentage)  
 {  
     if (percentage < 0 || percentage > 100)  
         throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");  
  
     // Encoder parameter for image quality   
     EncoderParameter qualityParam = newEncoderParameter(System.Drawing.Imaging.Encoder.Quality, percentage);  
     // JPEG image codec   
     ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");  
     EncoderParameters encoderParams = new EncoderParameters(1);  
     encoderParams.Param[0] = qualityParam;  
     System.Drawing.Image img = Resize(image, 300, 300);  
     img.Save(destinationPath, jpegCodec, encoderParams);  
 }  
  
 public static System.Drawing.Image Resize(System.Drawing.Image image, int width, intheight)  
 {  
     var res = new System.Drawing.Bitmap(width, height);  
     using (var graphic = System.Drawing.Graphics.FromImage(res))  
     {  
         graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;  
         graphic.SmoothingMode = SmoothingMode.HighQuality;  
         graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;  
         graphic.CompositingQuality = CompositingQuality.HighQuality;  
         graphic.DrawImage(image, 0, 0, width, height);  
     }  
     return res;  
 }  
 /// <summary>   
 /// Returns the image codec with the given mime type   
 /// </summary>   
 private static ImageCodecInfo GetEncoderInfo(string mimeType)  
 {  
     // Get image codecs for all image formats   
     ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();  
  
     // Find the correct image codec   
     for (int i = 0; i < codecs.Length; i++)  
         if (codecs[i].MimeType == mimeType)  
             return codecs[i];  
  
     return null;  
 }  
  
Please try the above solution in your end and let us know the result. If you still facing the issue kindly provide the below details, it will helpful for us to provide the precise solution on this.   
  
  • Complete sample  
  • Expected Output 
  • Image files
  
Regards,  
Sowmiya Loganathan  
 



LM Lindsay Miles June 17, 2020 02:20 AM UTC

Thanks very much for the code samples and info.

Unfortunately that still doesn't help if the image is stretched to fill the cell (col or col-span, row or row-span).
If I force cell size in left column to suit the image, that forces cell-row-height in the righthand column to be same (obviously)
That throws of the positioning of the diagram/image Title and KeyPoint cells...

Questions

- Does the doc.PageSettings.Width property include margins? is that actual page-width?
- Are ALL size properties in the Syncfusion.PDF assembly given in points? (not pixels)
- What is the resolution of the PDFs generated? 75dpi? higher? That will affect point or pixel dimensions...

- what about inserting an image into a cell but NOT as background?

When inserting images as background, they scale to the width of a col or a col-span already.
ALL I WANT out of this is to maintain image aspect ratio... like DO NOT stretch or shrink the image HEIGHT to fill the row or row-span.
Maintain image proportions!

I've attached a sample output pdf.

The images are always .png format.
ANY image will do. Simply set the images in the left hand column and maintain their proportion / aspect ratio.

I don't want to post any other code I have on this forum.

Please advise.

Thanks






Attachment: Diagram_Review1_f5a303f8.zip


SL Sowmiya Loganathan Syncfusion Team June 17, 2020 11:09 AM UTC

Hi Lindsay,    
   
Please find the details from below,   
   
- Does the doc.PageSettings.Width property include margins? is that actual page-width?   
Yes, document.PageSettings.Width includes the margin. If you want to set the page width without margin, please use the below code snippet,    
   
doc.PageSettings.Margins.All = 0;   
   
- Are ALL size properties in the Syncfusion.PDF assembly given in points? (not pixels)   
The unit of measurement used in Syncfusion PDF is in Points.    
- What is the resolution of the PDFs generated? 75dpi? higher? That will affect point or pixel dimensions...   
   
PDF is not dependent on resolution and we draw every element in the sale of 96 DPI.    
- what about inserting an image into a cell but NOT as background?   
   
As we said earlier, inserting images in a grid cell is of below two types.    
   
When inserting images as background, they scale to the width of a col or a col-span already.
ALL I WANT out of this is to maintain image aspect ratio... like DO NOT stretch or shrink the image HEIGHT to fill the row or row-span.  
 
Maintain image proportions!   
   
While inserting an image to grid cell using background or BeginCellLayout event handler, the image should be shrink or stretch if the image size is greater than cell width and height. If you want to add an image without stretch or shrink, you can set the height of the grid cell using below code snippet,   
   
PdfGridRow row1 = pdfGrid.Rows.Add();   
row1.Height = image.Height;   
   
  
Please let us know if you have any concerns on this.  
 
Regards, 
Sowmiya Loganathan  



LM Lindsay Miles June 17, 2020 12:20 PM UTC

Thanks again for following up and doing so quickly!
I really appreciate your efforts in helping with this!

Please see comments and questions below:
   
- Does the doc.PageSettings.Width property include margins? is that actual page-width?   
Yes, document.PageSettings.Width includes the margin. If you want to set the page width without margin, please use the below code snippet,    
   
 In that case, what is the default margin value?

doc.PageSettings.Margins.All = 0;   
   
- Are ALL size properties in the Syncfusion.PDF assembly given in points? (not pixels)   
The unit of measurement used in Syncfusion PDF is in Points.    
- What is the resolution of the PDFs generated? 75dpi? higher? That will affect point or pixel dimensions...   
   
PDF is not dependent on resolution and we draw every element in the sale of 96 DPI.    Very good to know
- what about inserting an image into a cell but NOT as background?   
   
As we said earlier, inserting images in a grid cell is of below two types.    
   The problem with the sample you posted on that is that not every row[0] cell[0] will have an image. It is difficult to insert into the right cell when the first cell in each row does not always require an image. See my sample pdf I attached to last post.
When inserting images as background, they scale to the width of a col or a col-span already.
ALL I WANT out of this is to maintain image aspect ratio... like DO NOT stretch or shrink the image HEIGHT to fill the row or row-span.  
 
Maintain image proportions!   
   
While inserting an image to grid cell using background or BeginCellLayout event handler, the image should be shrink or stretch if the image size is greater than cell width and height. If you want to add an image without stretch or shrink, you can set the height of the grid cell using below code snippet,   
   
PdfGridRow row1 = pdfGrid.Rows.Add();   
row1.Height = image.Height;   
   
If I do this and the image is 1200x wide and 900px high, the image scales down width-wise to fit the cell BUT the height is then distorted. 


I will try a few more things. It is so close to being right except the image distortion issues.

Will feedback or ask further question later.

Thanks again



SL Sowmiya Loganathan Syncfusion Team June 18, 2020 12:19 PM UTC

Hi Lindsay,    
   
In that case, what is the default margin value?   
    
The default margin value of the PDF document is 40.    
The problem with the sample you posted on that is that not every row[0] cell[0] will have an image. It is difficult to insert into the right cell when the first cell in each row does not always require an image. See the sample pdf I attached to last post.   
Using BeginCellLayout event handler, you can insert an image in any row (any cell) or particular row (particular) by checking the condition of the respective row is equal toargs.RowIndex or args.CellIndex.    
   
i.e.,    
private static voidPdfGrid_BeginCellLayout(object sender, PdfGridBeginCellLayoutEventArgs args)   
{   
    //Draw images one after another in single PDF cell   
    if (args.RowIndex == 1 && args.CellIndex == 0)   
    {   
        //Draw image    
    }   
}   
   
Note: We have one property to set the image position in the cell by using ImagePosition. Please refer the below code snippet for more details,   
   
PdfGridRow r1 = pdfGrid.Rows.Add();   
r1.Cells[0].ImagePosition = PdfGridImagePosition.Fit;   
r1.Cells[0].Style.BackgroundImage = image;   
   
This Enum contains Center, Fit, Stretch, and tile values. If this is suitable for your requirement, please make use of it.    
   
If I do this and the image is 1200x wide and 900px high, the image scales down width-wise to fit the cell BUT the height is then distorted.   
As we said earlier, to insert image in PdfGrid cell by using the below methods,    
   
  • Background image 
  • Using BeginCellLayout
   
By using the above image should be shrink or stretch if the image size is greater than the cell size. Other than this we do not contain any method to do this. So we could not able to proceed further in this.    
   
  
Regards, 
Sowmiya Loganathan 



LM Lindsay Miles June 19, 2020 01:23 AM UTC

I strongly suggest that Syncfusion modifies/amends the ImagePosition and PdfGridImagePosition.Fit (or an added enum) to maintain aspect ratio of any images inserted into cells. This is a serious limitation in the PDF engine you have.

I'm pretty sure anyone inserting images into a grid would want those images to NOT BE distorted in any way.

I have managed a work around checking page width and image size and doing some scaling to set row height.
Not ideal but it'll have to do for now.

QUESTION: How can I force a page-break?

When the end of page is reached, part of the image is on the first page, nothing on the second page, just blank space.
I'd like to check for page space somehow and insert a break, forcing a new page AND print next diagram and data to new page.

Can that be done?

Thank you again for your efforts.




SL Sowmiya Loganathan Syncfusion Team June 19, 2020 10:39 AM UTC

Hi Lindsay,    
   
I have checked with your requirement “Insert image in grid cell when page break”. While adding an image as background to the grid cell and if it is paginated to the next page, the whole image preserved on the first page and there is a space on the next page. We regret to let you know, we did not face the issue “part of the image on the first page and nothing on the second page”. Please refer the below code snippet for more details,    
   
Could you please provide us the below details for further analysis and provide a better solution on this,    
   
  • Complete sample or code snippet
  • Output document
   
Regards, 
Sowmiya Loganathan 


Loader.
Up arrow icon