Is there a way to find the page break locations in an xlsxwriter worksheet? - xlsxwriter

In my code I generate a worksheet that uses fields with text wrapping, so I don't know exactly how many lines will be on a page when xlsxwriter creates the worksheet. Due to limitations in the app into which I need to import the xlsx worksheet, I need to take my original worksheet and split it so that each page becomes a worksheet in a new workbook.
Can I somehow access the location of page breaks after running fit_to_pages(), or alternately, is there a way to know exactly how many rows will be used when you run text wrapping on a field?

Can I somehow access the location of page breaks after running fit_to_pages()
No. That isn't stored in the file format. Excel calculates that at runtime when it loads the file.
Excel also adjusts the height of cells containing wrapped text automatically at runtime. You could prevent this by specifying an explicit row height for the rows that contains the wrapped text so that their height isn't adjusted automatically. However, setting the height explicitly for wrapped text requires some sort of estimation, which takes us to the second part of your question.
or alternately, is there a way to know exactly how many rows will be used when you run text wrapping on a field?
The only way to do this with 100% accuracy would be to use some Windows API functions with bounding box calculations. I'm not sure if that is (non-theoretically) possible in Python and if it is it probably isn't portable.
So you are going to have to make some sort of compromise and use explicit row heights that will allow you to calculate the height of the printed page and thus the page break location but not have the nice automatically height adjusted cells for wrapped text.

Related

How do I replicate and center an object in an Excel worksheet using VBA?

I have some VBA that takes the contents of a few different worksheets, and prints them to PDF. I'm trying to add a watermark type effect to each page that gets printed. However, not every page will receive the same watermark. I have a textbox that will correctly get updated as the VBA is running, and will always have what I want my "watermark" to be. I've gotten to the point where I can copy the textbox and paste it in a specific location, but I need to be able to paste it in multiple locations, which will not always be the same. I'm looking for each page to contain the "watermark" and for it to be centered (and potentially resized down to the dimensions of the page in a case where the watermark is larger than the page). Additionally, the number of pages added to the PDF by the sheet is variable, but all pages should always receive the "watermark". I have virtually no background in VBA. The below code was produced by recording a macro.
Sheets("Sheet 1").Select
ActiveSheet.Shapes.Range(Array("TextBox 3")).Select
Selection.Copy
Sheets("Sheet 2").Select
Range("C16").SelectActiveSheet.Paste
I need the paste location to be dynamic and centered in the middle of the printed page. I also need the image to appear on each printed page.
Any help would be greatly appreciated.
Edit: One of the things the existing VBA does is print all the pages on the worksheet to PDF. It then changes values of the pages, and prints them to PDF as well. I need the watermark to update when the values do, which is currently working. The problem I am having is that when the values change, the number of rows change, and so does the page count. If I had a static page count I would just add the watermark (which is already updating as needed) everywhere it's supposed to be.

ssrs report viewer vs exported pdf page count

The number of pages displayed when viewed in ReportViewer and in exported PDF are differing.
Eg: 50 records are shown in one single page of Report Viewer. But when Exported to PDF 45 reords come in page 1 and the remaining come in page 2.
Soution Tried:
1)Removed Top and Bottom Margins.
2)Reduced "Interactive Page Size" to match the page count.
But it is not consistent, as it is behaving differently with different number of records.
Can anyone tell me how should I proceed to achieve sync between the ReportViewer and exported PDF ?
Thanks
Short answer - you can't do what you are trying to do: the different renderers handle pagination differently, but appropriately for their output.
The HTML renderer is optimised for screen-based reading and generally allows more content per page than the print renderer does as the print renderer is constrained by the paper size that it formats to. Thus the HTML renderer allows more content on fewer pages for a better browser experience whereas the print and PDF renderers have to conform strictly to the page length.
The best illustration of this is the Excel renderer - the Excel renderer renders the entire report onto a single worksheet in most cases (for reports with grouping and page breaks set on the group footer it will render each group on its own worksheet). You wouldn't want the Excel renderer to artificially create worksheets to try to "paginate" your report or to put it all in one worksheet but insert the header into the spreadsheet rows every "page". It does the appropriate thing which is to include all the data in one big worksheet even though that may be logically thought of as one big "page".
The HTML renderer page length is determined (more accurately, influenced) by the InteractiveHeight attribute of the report (in the InteractiveSize property in the Properties pane for the report). However, the interactive height is an approximation rather than a fixed page break setting and your page breaks may still not conform to the print version even if you set InteractiveHeight to the same length as your target page length. This is because the HTML renderer will vary the page length to group the data together better so the interactive page breaks happen around about, but not always exactly, where the interactive height is set.
This is what is happening in your scenario where the report viewer shows 50 records on one page but the PDF has 45 on the first page and 5 on the second page. The report viewer is making the decision that since there are only a few records left to display it will just include them all on the one page rather than force the user to scroll even though the interactive height will be exceeded. Thus you get a better user experience but a variance in pages between renderers. The important thing about the report is the data and the experience with working with that data in that renderer, not that the pages are the same length no matter how you look at it.
See this discussion of rendering behaviour for more information on why what you are trying to achieve isn't achievable. Just educate your users that the browser pagination is optimised for their viewing pleasure.

Possible to control PDF layout with iText?

I'm writing some logic to build a large single PDF file that our users can print at their convenience. I'm using Java's iText library (through Clojure's clj-pdf).
I'm trying to have the PDF show the same exact template form on every single page, however I can't seem to find any documentation or indication that one can have PDF content "fit to a page".
The text in these forms varies a little bit, so there's a chance it might require more of fewer text lines per page. This means that the content has a chance of spilling over to the next page, or being too short, making the next page creep up into the previous one, breaking the requirement of "one form per page" for the rest of the document.
I'm trying to figure out if my option is pretty much only to manually check the length of the text on each page and potentially crop it by hand if I goes over n lines, or if the PDF format somehow supports a smart way of having paragraphs+tables+headings all fit in one page. Some UI systems allow you to control how spill-over is handled, anywhere from cropping to resizing the font, so I'm curious if PDF supports anything of that sort.
Edit: ended up going with pagebreaks for simplicity, wasn't aware of that option when I wrote this question.
If you want to take control over the space taken by text, for instance to fit it on a single page, the way to go would be to create a ColumnText object and to add the content in simulation mode. If the text fits the page, add it for real. If it doesn't, use a smaller font size. This is demonstrated in the MovieAds example where snippets of text are fitted into AcroForm fields.

A Text value change on Powerpoint by using OpenXml doesn't fit

I use OpenXml for creating custom powerpoint presentation in this way: I put a keyword on the presentation, I found it during process with OpenXml and change the text value. Everything work fine but the fit option doesn't work at first.
The text box has options "Autofit: Shrink text on overflow; Wrap text in shape: On"
After my process, the new text appear on the right place but the autofit is not done, I need to click on the text box and make a input for see the autofit work. I think that PowerPoint only check option after a modification.
What I want is the autofit option is called at the end of the process. Can anyone help me?
I hope you understand what I want to do.
Thanks.
It's not possible using just OpenXML. The <a:normAutofit/> tag is used by a client application, such as PowerPoint, to render the text larger or smaller, as needed. OpenXML doesn't actually render anything, so until the client does, it will just read the text as if it is not auto-fitted.
There are a few options to think of to control this - none of them great however. One would be to use VSTO or VBA in PowerPoint to check all shapes on PPTX open and if they have a AutoFit tag, to re-render them. A second way would be to do all the font measurements yourself based on the shape's width & height and then set the font scale to the appropriate percentage. Another would be to make a textbox large enough to fit the largest amount of text you will ever insert and then turn autofit off.
Sorry this doesn't really help you immediately. I've done tons of research on this particular subject and it's all bad news.

Dynamic Data in an RDLC Report Footer across Multiple Pages

I created an RDLC report (based on a stored procedure) that contains lists. I need to display data from one of those lists in the report footer across every page. However this data only shows in a list on the first page, so that is the only page on which it shows in the footer also. I’ve researched this but haven’t found much information. Does anyone have a solution for this?
Something you can try, don't know for sure if it will work. Create a formula that returns the data you want to display, then put the formula field on a text area in the footer.
I ended up placing a textbox in the second page area, setting the text color to white and sending it to the back. If I hid the textbox (or table - I tried that too), the footer object could not reference it. So, setting the text color to white and placing it behind another object worked. It seems like this is a kludgy way to do a simple report operation but is apparently necessary.