PHPSpreadsheet Fails to Save Line Chart Loaded From Template (Locked by 'another user') - phpspreadsheet

I am running into a problem where phpspreadsheet will not write out a line chart from an xlsx file I'm using as a template.
I get two error messages when opening the spreadsheet:
We found a problem with some content in 'Hello World.xlsx'. Do you want us to try to recover as much as we can? If you trust the source of the workbook, click Yes
Hello World.xlsx is locked for editing
by 'another user'
Open 'Read-Only' or click 'Notify' to open read-only and receive notification when the document is no longer in use.
<?php
// ... snip
$reader = IOFactory::createReader($inputFileType);
$reader->setIncludeCharts(true);
$spreadsheet = $reader->load($inputFileName);
// ... snip
// populate chart data
$sheet = $spreadsheet->getSheetByName('Ratios');
// reverse order, so populate "backwards"
for($endingRow = 14; ($endingRow > 1) && ($row = $last13Ratios->nextRecord()); $endingRow--) {
$sheet->setCellValue('A'.$endingRow, $row->date);
$sheet->setCellValue('B'.$endingRow, $row->percent60/100);
$sheet->setCellValue('C'.$endingRow, $row->percent90/100);
$helper->log(print_r($row));
}
// ... snip
$writer = new XlsxWriter($spreadsheet);
$writer->setIncludeCharts(true);
$callStartTime = microtime(true);
$writer->save($saveFileName);
$helper->logWrite($writer, $saveFileName, $callStartTime);
$spreadsheet->disconnectWorksheets();
die();
If I put fake data in the template, it appears to work. But I don't want fake data, just in case something goes haywire. Better to have no information than wrong information.

The short answer is to put a space ' in the upper left cell of the section being used for data in the template.
Note that the data type appears to make a difference, also: a date instead of a string will fail.
Be sure to use the single quote mark to designate it as a string, otherwise excel will ignore the space when you save it.

Related

PhpSpreadSheet how to have a new line?

Good day everyone i want to achieve a new line in my spreadsheet cause i had two to three values here
This code over here has a protection so the viewers cannot edit easily in excell they must have password on the admin to be enable to edit.
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$spreadsheet->getActiveSheet()->getProtection()->setSheet(true);
$spreadsheet->getActiveSheet()->getProtection()->setSort(true);
$spreadsheet->getActiveSheet()->getProtection()->setInsertRows(true);
$spreadsheet->getActiveSheet()->getProtection()->setFormatCells(true);
$spreadsheet->getActiveSheet()->getProtection()->setPassword('test');
$spreadsheet->getActiveSheet()->getStyle('D')->getAlignment()->setWrapText(true);
$spreadsheet->getDefaultStyle()
->getFont()
->setName('Times New Roman')
->setSize(14);
$sheet->setCellValue('A1', 'Control Number');
$sheet->setCellValue('B1', 'Requesting Unit');
$sheet->setCellValue('C1', 'Project Details');
$sheet->setCellValue('D1', 'Attached Transaction Form');
This line of code uses to fetch the data in the database in this scenario my attached form has two to three values so thats why i want to create a break or a new line.
$data = $this->m->getlog1();
$slno = 1;
$start = 2;
foreach($data as $d){
$sheet->setCellValue('A'.$start, $d->control_number);
$sheet->setCellValue('B'.$start, $d->requesting_unit);
$sheet->setCellValue('C'.$start, $d->project_details);
$sheet->setCellValue('D'.$start, $d->attached_form);
$start = $start+1;
$slno = $slno+1;
}
You have to use line breakes in the text and
$spreadsheet->getActiveSheet()->getStyle('A1')->getAlignment()->setWrapText(true);
For more Information see documentation.
According to this commit this commit this will be automatically included in future releases.
Maybe you must/will use some auto fit then take a look to this code.

How to parse an unconventional file with Talend?

I have a file shape like this :
How can I parse a file like this with Talend Open Studio ?
Here's what I tried :
In the tJavaRow, the input is the whole file in a single row. I split it and parse it manually. But I can't figure out how to create an output row for each OBJ in the file.
Is this the "Right" way of doing it ? Or is there a specific component for this type of files ?
But I can't figure out how to create an output row for each OBJ in the file
You can do this by using the tJavaFlex component:
Put your raw content in the globalMap by connecting it to tFlowToIterate
Put your split-and-parse logic in the "Start Code" part of tJavaFlex, using the contents you made available in step 1
Start a loop in the "Start Code" part of tJavaFlex (e.g. for each object)
Define your output schema in tJavaFlex
In the "Main Code" part of tJavaFlex, map your parsed object to the columns of your output row
Dont forget to close your loop in the "End Code" part of tJavaFlex
I layed out a quick example, with no parsing logic. But since you already got this down, I think it should be sufficient:
Start Code
String[] lines = ((String)globalMap.get("row1.content")).split("\r\n");
for(String line : lines) { // starts the "generating" loop
Main Code
row2.key = line; // uses the "generating" loop
End Code
} // closes the "generating" loop

Saving a composite datawindow in PowerBuilder

Is there a way to save results in a composite datawindow as a text or excel spreadsheet? Powerbuilder states for composites the format to save it is PSReport. That doesn't work for what I'm trying to do. Is there any other workaround for this issue?
A composite datawindow may contain any number of nested datawindows. So if memory serves, you cannot save the entire composite datawindow as data in a meaningful way (SaveAs will just give you a one-line bit of meaningless data), but you CAN save each of the nested datawindows inside the composite.
Here is some PFC code I wrote (for inside a menu item) which makes a copy of a nested report and then executes a SaveAs (dialog in this case):
//must create a 'dummy' datawindow,
//and put the data on the nested report into it
u_dw ldw_Temp
Window lw_Parent
String ls_Syntax, ls_Error
If Not IsValid(i_dwo) Then
MessageBox('Unexpected Error', &
'The pointer to the datawindow object was invalid. Contact Systems.')
Return
End If
If i_dwo.Type = 'report' Then
//continue
Else
MessageBox('Unexpected Error', &
'The pointer did not refer to a report. Contact Systems.')
Return
End If
If idw_Parent.of_GetParentWindow(lw_Parent) = 1 Then
ls_Syntax = i_dwo.object.datawindow.syntax
If lw_Parent.OpenUserObject(ldw_Temp) = 1 Then
If ldw_Temp.Create(ls_Syntax,ls_Error) = 1 Then
ldw_Temp.Object.Data.Primary = i_dwo.Object.Data.Primary
ldw_Temp.Event pfc_SaveAs()
Else
If IsNull(ls_Error) Or ls_Error = '' Then ls_Error = '<unknown error>'
MessageBox('Error','Error creating datawindow object: ' + ls_Error)
End If
lw_Parent.CloseUserObject(ldw_Temp)
Else
MessageBox('Error','Error creating datawindow control on ' + lw_Parent.ClassName())
End If
Else
MessageBox('Error','Unable to obtain pointer to the parent window.')
End If
Basically this code gets the syntax of the datawindow object underlying the nested report (ls_Syntax = i_dwo.object.datawindow.syntax above), then creates a datawindow control on the parent form and loads that syntax into it, and then copies the data from the one into the other. Finally it calls SaveAs on the copy, and the user is presented with a dialog asking where they want to save the data from the nested report and in what format.
You could automate this so that it saves each nested report as a separate file, and then if you like you could automate the formation of those separate files into a single file (sheets inside a workbook, appended text files, etc).
There are other ways to do what you are asking, depending on what exactly you are trying to accomplish.
The i_dwo variable was loaded in the right-mouse up even of the datawindow control (the dwo event variable there).
That may get you running, please ask questions if you have any.

New Google Spreadsheets publish limitation

I am testing the new Google Spreadsheets as there is a new feature I really need: the 200 sheets limit has been lifted (more info here: https://support.google.com/drive/answer/3541068).
However, I can't publish a spreadsheet to CSV like you can in the old version. I go to 'File>Publish to the web' and there is no more options to publish 'all sheets' or certain sheets and you can't specify cell ranges to publish to CSV etc.
This limitation is not mentioned in the published 'Unsupported Features' documentation found at: https://support.google.com/drive/answer/3543688
Is there some other way this gets enabled or has it in fact been left out of the new version?
My use case is: we retrieve Bigquery results into the spreadsheets, we publish the sheets as a CSV automatically using the "publish automatically on update" feature which then produces the CSV URL which gets placed into charting tools that read the CSV URL to generate the visuals.
Does anyone know how to do this?
The new Google spreadsheets use a different URL (just copy your <KEY>):
New sheet : https://docs.google.com/spreadsheets/d/<KEY>/pubhtml
CSV file : https://docs.google.com/spreadsheets/d/<KEY>/export?gid=<GUID>&format=csv
The GUID of your spreadsheet relates to the tab number.
/!\ You have to share your document using the Anyone with the link setting.
Here is the solution, just write it like this:
https://docs.google.com/spreadsheets/d/<KEY>/export?format=csv&id=<KEY>
I know it's weird to write the KEY twice, but it works perfectly. A teammate from work discovered this by opening the excel file in Google Docs, then File -> Download as -> Comma separated values. Then, in the downloads section of the browser appears a link to the CSV file, like this:
https://docs.google.com/spreadsheets/d/<KEY>/export?format=csv&id=<KEY>&gid=<SOME NUMBER>
But it doesn't work in this format, what my friend did was remove "&gid=<SOME NUMBER>" and it worked! Hope it helps everyone.
If you enable "Anyone with the link sharing" for spreadsheet, here is a simple method to get range of cells or columns (or whatever your feel like) export in format of HTML, CSV, XML, JSON via the query:
https://docs.google.com/spreadsheet/tq?key=YOUR-KEY&gid=1&tq=select%20A,%20B&tqx=reqId:1;out:html;%20responseHandler:webQuery
For tq variable read query language reference.
For tqx variable read request format reference.
Downside to this is that your doc is still availble in full via the public link, but if you want to export/import data to say Excel this is a perfect way.
It's not going to help everyone, but I've made a PHP script to read the HTML into an array.
I've added converting back to a CSV at the end. Hopefully this will help some people who have access to PHP.
$html_link = "https://docs.google.com/spreadsheets/d/XXXXXXXXXX/pubhtml";
$local_html = "sheets.html";
$file_contents = file_get_contents($html_link);
file_put_contents($local_html,$file_contents);
$dom = new DOMDocument();
$html = #$dom->loadHTMLFile($local_html); //Added a # to hide warnings - you might remove this when testing
$dom->preserveWhiteSpace = false;
$tables = $dom->getElementsByTagName('table');
$rows = $tables->item(0)->getElementsByTagName('tr');
$cols = $rows->item(0)->getElementsByTagName('td'); //You'll need to edit the (0) to reflect the row that your headers are in.
$row_headers = array();
foreach ($cols as $i => $node) {
if($i > 0 ) $row_headers[] = $node->textContent;
}
foreach ($rows as $i => $row){
if($i == 0 ) continue;
$cols = $row->getElementsByTagName('td');
$row = array();
foreach ($cols as $j => $node) {
$row[$row_headers[$j]] = $node->textContent;
}
$table[] = $row;
}
//Convert to csv
$csv = "";
foreach($table as $row_index => $row_details){
$comma = false;
foreach($row_details as $value){
$value_quotes = str_replace('"', '""', $value);
$csv .= ($comma ? "," : "") . ( strpos($value,",")===false ? $value_quotes : '"'.$value_quotes.'"' );
$comma = true;
}
$csv .= "\r\n";
}
//Save to a file and/or output
file_put_contents("result.csv",$csv);
print $csv;
Here is another temporary, non-PHP workaround:
Go to an existing NEW google sheet
Go to "File -> New -> Spreadsheet"
Under "File -> Publish to the web..." now has the option to publish a csv version
I believe this is actually creating an old Google sheet but for my purposes (importing google sheet data from clients or myself into R for statistical analysis) it works until they hopefully update this feature.
I posted this in a Google Groups forum also, please find it here:
https://productforums.google.com/forum/#!topic/docs/An-nZtjaupU
The correct URL for downloading a Google spreadsheet as CSV is:
https://docs.google.com/spreadsheets/export?id=<ID>&exportFormat=csv
The current answers do not work anylonger. The following has worked for me:
Do File -> "Publish to the web" and select 'start publishing' and the format. I choose text (which is TSV)
Now just copy the URL there which will be similar to https://docs.google.com/spreadsheet/pub?key=YOUR_KEY&single=true&gid=0&output=txt
That new feature appears to have disappeared. I don't see any option to publish a csv/tsv version. I can download tsv/csv with the export, but that's not available to other people with merely the link (it redirects them to a google docs sign-in form).
I found a fix! So I discovered that old spreadsheets before this change were still allowing only publishing certain sheets. So I made a copy of an old spreadsheet, cleared the data out, copy and pasted my current info into it and now I'm happily publishing just a single sheet of my large spreadsheet. Yay
I was able to implement a query to the result, see this table
https://docs.google.com/spreadsheets/d/1LhGp12rwqosRHl-_N_N8eTjTwfFsHHIBHUFMMyhLaaY/gviz/tq?tq=select+A,B,I,J,K+where+B%3E=4.5&pli=1
the spreadsheet fetches data from earthquake, but I just want to select MAG 4.5+ earthquakes so it makes the query and the columns, just a problem:
I cannot parse the result, I tried to decode as json but was not able to parse it.
I would like to be able to show this as HTML or CSV or how to parse this ? for example to be able to plot it on a Google Map.

jQuery autocomplete not displaying my encoded values

I am working from this example: http://jqueryui.com/demos/autocomplete/#remote and I am encoding the output like this:
$rows = array();
while($r = mysql_fetch_assoc($category_result))
{
$rows[] = $r;
error_log ("rows: ".$rows[0]);
}
echo json_encode($rows);
But the dropdown on the other side shows nothing. Here is my test page: http://problemio.com/test.php - if you enter "ho" it matches 2 results in the database, but they are not getting displayed for some reason. Any idea why?
Thanks!!
The properties should be named label and value. From the JQuery UI demo page you linked to:
The local data can be a simple Array of Strings, or it contains
Objects for each item in the array, with either a label or value
property or both. The label property is displayed in the suggestion
menu.
So you would need to rename category_name to label either in PHP or later on in your JavaScript source handler function. The latter would require you to replace the PHP URL with a callback function like in the remote example. That way you could get the data any way you want (e.g. by jQuery.getJSON()) and work with it before it gets handed over to the suggestion box.
Hope this helps.
Regarding your comment, this should do it:
$rows = array();
while ($r = mysql_fetch_array($category_result)) {
$rows[] = array("label" => $r["category_name"]);
}
echo json_encode($rows);

Resources