I am builiding an excel file using phpExcel. I fill all the cells I need and at last I set some formatting on the excel file. One of the things I'm doing is to adjust the cell width but I am getting a strange result. None of the columns are set to the right width. Some are set to a larger width and the other are left to the original width. I don't use bold font anywhere but just some background color on the first row.
This is my actual code for formatting:
$header = 'A1:EK1';
$ews->getStyle($header)->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID)->getStartColor()->setARGB('ff00008b');
$style = array(
'font' => array('bold' => false,
'color' => array('rgb' => 'FFFFFF'),
'size' => 12,
'name' => 'Verdana'),
'alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_CENTER,),
);
$ews->getStyle($header)->applyFromArray($style);
for ($col = ord('A'); $col <= ord('HK'); $col++)
{
$ews->getColumnDimension(chr($col))->setAutoSize(true);
}
I have had a look at many questions on SO and googled a bit but I have found issues only in case of csv files (mine is a xlsx) or bold font (I don't have at all). Since I am still learning on how this library works I am looking for some help
If a column is set to AutoSize, PHPExcel attempts to calculate the column width based on the calculated value of the column (so on the result of any formulae), and any additional characters added by format masks such as thousand separators.
By default, this is an estimated width: a more accurate calculation method is available, based on using GD, which can also handle font style features such as bold and italic; but this is a much bigger overhead, so it is turned off by default. You can enable the more accurate calculation using
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);
However, autosize doesn't apply to all Writer formats... CSV files do not support any formatting, just data, so column width (which is formatting) cannot be applied when you write a CSV file
$objPHPExcel->getActiveSheet()->getColumnDimension(COLUMN)->setAutoSize(true);
Related
My task is to check several docx documents for font properties, like font name, size, boldness, italic etc. I do not want to change anything, just validate if there are correct values.
I created a small test document, with text "Foo-bar" and I have updated the font name to Garamond from the default, but have not changed the font size.
Now I am able to read the font name from the document, but when I try to read the font size, I get None.
from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
def check_para_props(doc, paralist, ffamily, fsize, paligin):
pargs = doc.paragraphs
for i in paralist:
para = pargs[i]
print(i, para.text)
for run in para.runs:
print(run.font.name, run.font.size)
worddoc = Document('Foo-bar.docx')
# pass the document, the paragraphs list which should be tested
# and the expected values
check_para_props(worddoc, (0, ), 'Garamond', 11, WD_ALIGN_PARAGRAPH.JUSTIFY)
Output:
0 Foo-bar
Garamond **None**
I assume, there is some default values in docx for the unchanged values, like font-size, but have not found, how could I read them from the document. In python-docx documentation I have not found an API call for it: https://python-docx.readthedocs.io/en/latest/index.html
I have checked the style section, which is readable, but I don't think, this is set there.
Checked API documentation: https://python-docx.readthedocs.io/en/latest/index.html
Word is able to export document in XML format, but still I have doubts how to read the font size.
In that article, I read the about the inheritance of the properties: https://www.toptal.com/xml/an-informal-introduction-to-docx
It tells, to get the end result of a character’s properties you should:
Use default run/paragraph properties
Append run/paragraph style properties
Append local run/paragraph properties
Append result run properties over paragraph properties
Ok, still how may I read the default properties using python-docx?
Please advise!
Thank you in advance!
I have a situation where I have a report that is normally displayed in a jsp, and now I have a print where those multiple instances of said page needs to be included multiple times, so this is a combined report kind of thing. To circumvent issues that would arise from adding values to the model with the same key we came up with this way to include the jsp.
<c:forEach var="prodTest" items="${listProductionTest}">
<div style="display:block" id="chargeReport${prodTest.report.recId}">
</div>
<script type="text/javascript">
$.get("ChargeReportContent?recId=${prodTest.report.recId}", function( data ) {
$("#chargeReport${prodTest.report.recId}").html(data);
});
</script>
ChargeReportContent is an endpoint that returns the jsp with the values. It retrieves data correctly however the divs height is all wrong causing the both reports to overlap. It seems auto height gives itself enough height to only include the first part of the report.
display block doesnt seem to work. These reports should each have size of around 1500px but putting the height as a fixed value is not really an option as the size can change depending on the report or updates.
Plz help!
what's the position of the elements inside the div?
Make sure they are not fixed, absolute or have float set.
Divs are set to display block by default, you might try to set it to flex
A colleague suggested that this is because the html was filled programmatically, the size was not accurate. We never figured out a clean way to fix this, but the best we came up with is to calculate the needed height ourselves and then set it. For example
the title is always 92px, recipe is always 256px, Reportlines size= 42+(21(materials+1)), notes part is 23px if there are no notes, 42 if there is a note, etc.
if in the JSP we could not easily retrieve a number of Alarms we made an invisible input to store the value and is added by the model like
<input id="alarmCounter${report.recId}" style="display: none" value="${alarmCount}"></input>
and then we retrieve the val to use it in the calculation.
After we find the total we just set it in the get that gets the included page
$.get("ChargeReport?recId=${prodTest.report.recId}", function( data ) {
$("#chargeReport${prodTest.report.recId}").html(data);
let alarmCount = 0;
alarmCount =parseInt($('#alarmCounter${prodTest.report.recId}').val());
var chartsize = 400*($('#chartExists${prodTest.report.recId}').val() == 'true' ? 1 : 0)
var pixelsNeeded= 92 + 256 + 205
+ 42+ 21*(${fn:length(prodTest.report.reportLines)}+1)
+ 21*(alarmCount+2)
+19+24*${!empty prodTest.report.comment}
+ chartsize + 51
+50;
$('#chargeReport${prodTest.report.recId}').css("height",pixelsNeeded+"px");
I have this dataframe:
And I want to make a horizontal stacked bar chart that displays the same information as this chart:
I have generated this code:
chart = alt.Chart(df_q4).mark_bar().encode(
x = alt.X('value:Q', axis=None),
color=alt.Color('color_code:N', scale=None),
).facet("title:N"
).properties(
width=400,
height=700)
chart
However it throws this error:
SchemaValidationError: Invalid specification
altair.vegalite.v4.api.Chart, validating 'required'
'data' is a required property
alt.FacetChart(...)
I am not sure why I cannot facet. I have also tried encoding the facet object within the chart encoding, and that did not work as well.
I also would like to incorporate some code into my chart that shows only the titles, colors, and values pertaining to a specific season. This will be via wrapping the code within a function that's something like:
define color_palette(season):
Facet charts do not support width or height properties. Perhaps you meant this?
chart = alt.Chart(df_q4).mark_bar().encode(
x = alt.X('value:Q', axis=None),
color=alt.Color('color_code:N', scale=None),
).properties(
width=400,
height=700
).facet(
"title:N"
)
I'm afraid that this question does not have an answer, but here it goes.
What I am trying to do is get people to fill in various information about them selves in my website, and echo all of it in a HTML template file (which gets converted into PDF later). Since all users have variable amounts of entries and entry lengths, it's impossible to predict the end result height of the document.
In other words: the more info a user gives about them selves, the higher in size the document gets. And there is no way to set DOMPDF to generate PDF heights according to the end result of the HTML template.
Am I missing a solution right under my nose here?
There is not a built-in way to do this, but that doesn't mean it is not possible. You happen to be the second person to ask this and that first time I did manage come up with a way it can be done.
The following comes from an original post on the dompdf support group.
First, you need to make a minor modification to the stylesheet of your document. You want to set the top and bottom page margins to zero so they don't add in to the height calculation. So in your first-pass HTML add the following additional style declaration:
#page { margin-top: 0px; margin-bottom: 0px; }
Next, you have to determine what the best first-pass document size will be. I was using a simple document, so I went with a simple 8cm x 8cm page size. You'll probably want to use a larger height to avoid any bugs related to paging. 8cm is roughly 226.77pt. So I set up the first pass to use a document defined with the appropriate dimensions:
$dompdf = new DOMPDF( );
$dompdf->set_paper( array( 0 , 0 , 226.77 , 226.77 ) );
$dompdf->load_html( $first_pass_html );
$dompdf->render( );
Then we get the number of pages that resulted from this pass and unset the $dompdf variable so we can do our second pass:
$page_count = $dompdf->get_canvas( )->get_page_number( );
unset( $dompdf );
Finally, render the document a second time using a page height calculated from the page height used in the first pass multiplied by the number of pages generated (plus a little extra padding to accommodate margins).
$dompdf = new DOMPDF( );
$dompdf->set_paper( array( 0 , 0 , 226.77 , 226.77 * $page_count + 20 ) );
$dompdf->load_html( $original_html );
$dompdf->render( );
$dompdf->stream( 'sample.pdf' , array( 'Attachment' => 0 ) );
I am currently in need to get the real height of a character. I am aware of the functions like getDecsent(), getAscent(), ... but they only allow to get values regarding the hole font (in its context). I also tried the way using getStringBounds(), but that is the same story.
Like the title says, I am looking for a way to get the height value of just one char at a time.
For example 'N' is higher then 'n', 'I' just a little bit higher then 'i' and so on
Thanks for your time
Use this
Rectangle2D bounds = font.getStringBounds("put your string here", context);
//font can be set to whatever you want
//my suggestion is that you use the same font for both characters
//context is a object of FontRenderContext
System.out.println(bounds.getHeight());
//Instead of just printing it you could do this a second time and compare the 2 strings