PhpSpreadsheet read xlsx file not correctly. Wrong reading empty combined cells - phpspreadsheet

I have the following excel table:
and the following code to turn it into html table:
<style>
table, th, td {
border: 1px solid black;
}
</style>
<?php
error_reporting(E_ALL);
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Writer\Html;
$fileExcel = tempnam(sys_get_temp_dir(), 'excel_');
$blob = file_get_contents('./test.xlsx');
file_put_contents($fileExcel, $blob);
$reader = new Xlsx();
$spreadsheet = $reader->load($fileExcel);
unlink($fileExcel);
$writer = new Html($spreadsheet);
$sheetData = $writer->generateSheetData();
echo $sheetData;
The result seems corrupted:
I tried to find some setting on the documentation, but I did not find anything. Any ideas how to fix this behavior?

Related

DOMDocument - How to get all inner text except from style/script tags?

I spent so much time on a very simple thing and had to post here on StackOverflow
I want to get all inner text except the script/style tags
$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;
$html = <<<EOD
<div>
<script>var main=0</script>
<div>
<p>my</p>
<script>var inner=0</script>
</div>
<p>text</p>
only
</div>
EOD;
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
echo $entries = $xpath->query('//*[not(self::script)]')->item(0)->nodeValue;
gives me
var main=0 my var inner=0 text only
and also tried
$entries = $xpath->query('//*[not(self::script)]');
foreach ($entries as $entry) {
if ($entry->tagName == 'style' || $entry->tagName == 'script') {
continue;
}
echo preg_replace('/\s\s+/', ' ', $entry->nodeValue);
}
gives me
var main=0 my var inner=0 text only var main=0 my var inner=0 text only var main=0 my var inner=0 text only my var inner=0mytext
I tried several xpaths but it doesn't work
my desired output is my text only
I am a Scrapy developer and I do that easily in Scrapy, but having a bad time with PHP today
Unfortunately, PHP doesn't support xpath 2.0 (and, IIRC, neither does Scrapy), so the name() method which would have made it easy, isn't available...
The closest thing I can think of is the following, which should get you close enough (note that, because there is no <style> tag in your $html, I only focused on <script>):
$entries = $xpath->query('//*[not(./text()/parent::script)]/text()');
foreach ($entries as $entry) {
echo trim($entry->textContent) . " ";
}
Output:
my text only

How to customize the volusion store and integrate a "get a quote" option

I want to customize the store and have an option for the users to get a quote for the products, once clicked on the option it will send mail to admin of store about the same along with the product ID
Let me know how can this be achieved ?
I did something similar ... added a Make Offer button for any product over X amount of money. Here's what my code in the template.html looks like...
var price = $("span[itemprop='price']").html();
if ( price != null && price != 'undefined' ) {
price = price.replace("$", "");
price = price.replace(",", "");
var pname= $("span[itemprop='name']").html();
pname= pname.replace(/\W+/g, "_")
var pcode = $('.product_code').html();
if ( price > 50 )
{
$('.vCSS_input_addtocart').after('<p><input type="button" style=" text-shadow: -1px -1px 0 #006d72, 1px -1px 0 #006d72, -1px 1px 0 #006d72, 1px 1px 0 #006d72;border-radius: 6px; border: 1px solid #6E2B62; background-color:#009DA5; color:white" value="Make An Offer" onclick="window.open( \'/v/vspfiles/makeanoffer.asp?ProductCode='+pcode+'&price='+price+'&pname='+pname+' \',\'_blank\', \'width=300px, height=500px\' ) " />');
Then I have a custom ASP page that handles the email, which is another can of worms. You could more easily use the built-in email form, which is explained here...
https://support.volusion.com/hc/en-us/articles/209448057-How-to-Create-a-Storefront-Email-Contact-Form
Good luck!

Make less-rails add line numbers as comment

Is there any way to configure less-rails so that it shows the line number of original sources as comments? And is it possible to enable source mapping?
Consider the following example:
file1.less
body {
background-color: black;
}
file2.less
body {
padding: 20px;
}
application.css.less
#import "file1";
#import "file1";
What I get:
body {
background-color: black;
}
body {
padding: 20px;
}
What I want
/* file1.less line: 1 */
body {
background-color: black;
}
/* file2.less line: 1 */
body {
padding: 20px;
}
Or is there any other easier way to find out which rule belongs to which file?
Update
When configuring my application, the config.less only contains the following:
{:paths=>
[#<Pathname:/home/yan-foto/.../vendor/less>,
#<Pathname:/home/yan-foto/.../node_modules/bootstrap-datetimepicker>,
#<Pathname:/home/yan-foto/.../node_modules/bootstrap-slider>],
:compress=>false}
Open the vendor/bundle/ruby/1.9.1/gems/less-2.6.0/lib/less/parser.rb file and replace (around line 54):
end
#parser = Less::JavaScript.exec { Less['Parser'].new(env) }
with:
end
env['dumpLineNumbers'] = 'comments';
#parser = Less::JavaScript.exec { Less['Parser'].new(env) }
Based on https://github.com/metaskills/less-rails#configuration you should try:
MyProject::Application.configure do
config.less.line-numbers << "comments"
config.less.compress = true
end
When the preceding works as expected you could also consider to use CSS sourcemaps:
MyProject::Application.configure do
config.less.source-map = true
config.less.source-map-map-inline = true
end
I really don't find the line config.less.line-numbers << "comments" in
docs
I fact my answer is only a suggestion and i was not able to test it. The above suggest that you are able to set some option for the Less compiler.
You can also find this option by running lessc without any argument:
-------------------------- Deprecated ----------------
--line-numbers=TYPE Outputs filename and line numbers.
TYPE can be either 'comments', which will output
the debug info within comments, 'mediaquery'
that will output the information within a fake
media query which is compatible with the SASS
format, and 'all' which will do both.
--verbose Be verbose.
and I am sure that it has a syntax error because of the dash between line
and numbers
I bet you are right about that. You should possible use: config.less.dumpLineNumbers and config.less.sourceMap
Or in your config.less: :dumpLineNumbers>comments

How to parse Markdown in PHP?

First, I know, there already is a Markdown parser for PHP.
I also took a look to this question but it doesn't answer to my question.
Obviously, even if the title mention PHP, if it's language agnostic, because I'd like to know what are the step I've to go through to do that.
I've read about PEG, but I've to admit, I didn't really understand the example provided with the PHP parser.
I've also read about CFG.
I've found Zend_Markup_Parser_Textile which seems to construct a so called "Token Tree" (what's about it?) but it currently unusable. (Btw, Textile is not Markdown)
So, concretely, how would you go to this?
Obviously I though about using Regex but, I'm afraid.
Because Markdown supports several syntaxes for the same element (Setext and atx).
Could you give some starting point?
You should have a look at Parsedown.
It parses Markdown text the way people do. First, it divides texts into lines. Then it looks at how these lines start and relate to each other. Finally, it looks for special characters to identify inline elements.
There is PHP Markdown Extra that seems to be popular, you could start by looking at its source.
Also, there is an object-oriented implementation of Markdown which is faster: markdown-oo-php
Ciconia - A New Markdown Parser for PHP is a good one I found.
You just need 3 things to do :
1.Install Ciconia and parse file according to the document.
2. Add corresponding css theme to make it nice, like github markdown style or here.
3. Add syntax highlighting javascript, like google Javascript code prettifier.
Then everything will look pretty good.
If you want a complete example, here is my working demo for github style markdown:
<?php
header("Content-Type: text/html;charset=utf-8");
require 'vendor/autoload.php';
use Ciconia\Ciconia;
use Ciconia\Extension\Gfm;
$ciconia = new Ciconia();
$ciconia->addExtension(new Gfm\FencedCodeBlockExtension());
$ciconia->addExtension(new Gfm\TaskListExtension());
$ciconia->addExtension(new Gfm\InlineStyleExtension());
$ciconia->addExtension(new Gfm\WhiteSpaceExtension());
$ciconia->addExtension(new Gfm\TableExtension());
$ciconia->addExtension(new Gfm\UrlAutoLinkExtension());
$contents = file_get_contents('Readme.md');
$html = $ciconia->render($contents);
?>
<!DOCTYPE html>
<html>
<head>
<title>Excel to Lua table - Readme</title>
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
<link rel="stylesheet" href="./github-markdown.css">
<style>
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
}
</style>
</head>
<body>
<article class="markdown-body">
<?php
# Put HTML content in the document
echo $html;
?>
</article>
</body>
</html>
Using regexes.
<?php
/**
* Slimdown - A very basic regex-based Markdown parser. Supports the
* following elements (and can be extended via Slimdown::add_rule()):
*
* - Headers
* - Links
* - Bold
* - Emphasis
* - Deletions
* - Quotes
* - Inline code
* - Blockquotes
* - Ordered/unordered lists
* - Horizontal rules
*
* Author: Johnny Broadway <johnny#johnnybroadway.com>
* Website: https://gist.github.com/jbroadway/2836900
* License: MIT
*/
class Slimdown {
public static $rules = array (
'/(#+)(.*)/' => 'self::header', // headers
'/\[([^\[]+)\]\(([^\)]+)\)/' => '<a href=\'\2\'>\1</a>', // links
'/(\*\*|__)(.*?)\1/' => '<strong>\2</strong>', // bold
'/(\*|_)(.*?)\1/' => '<em>\2</em>', // emphasis
'/\~\~(.*?)\~\~/' => '<del>\1</del>', // del
'/\:\"(.*?)\"\:/' => '<q>\1</q>', // quote
'/`(.*?)`/' => '<code>\1</code>', // inline code
'/\n\*(.*)/' => 'self::ul_list', // ul lists
'/\n[0-9]+\.(.*)/' => 'self::ol_list', // ol lists
'/\n(>|\>)(.*)/' => 'self::blockquote ', // blockquotes
'/\n-{5,}/' => "\n<hr />", // horizontal rule
'/\n([^\n]+)\n/' => 'self::para', // add paragraphs
'/<\/ul>\s?<ul>/' => '', // fix extra ul
'/<\/ol>\s?<ol>/' => '', // fix extra ol
'/<\/blockquote><blockquote>/' => "\n" // fix extra blockquote
);
private static function para ($regs) {
$line = $regs[1];
$trimmed = trim ($line);
if (preg_match ('/^<\/?(ul|ol|li|h|p|bl)/', $trimmed)) {
return "\n" . $line . "\n";
}
return sprintf ("\n<p>%s</p>\n", $trimmed);
}
private static function ul_list ($regs) {
$item = $regs[1];
return sprintf ("\n<ul>\n\t<li>%s</li>\n</ul>", trim ($item));
}
private static function ol_list ($regs) {
$item = $regs[1];
return sprintf ("\n<ol>\n\t<li>%s</li>\n</ol>", trim ($item));
}
private static function blockquote ($regs) {
$item = $regs[2];
return sprintf ("\n<blockquote>%s</blockquote>", trim ($item));
}
private static function header ($regs) {
list ($tmp, $chars, $header) = $regs;
$level = strlen ($chars);
return sprintf ('<h%d>%s</h%d>', $level, trim ($header), $level);
}
/**
* Add a rule.
*/
public static function add_rule ($regex, $replacement) {
self::$rules[$regex] = $replacement;
}
/**
* Render some Markdown into HTML.
*/
public static function render ($text) {
$text = "\n" . $text . "\n";
foreach (self::$rules as $regex => $replacement) {
if (is_callable ( $replacement)) {
$text = preg_replace_callback ($regex, $replacement, $text);
} else {
$text = preg_replace ($regex, $replacement, $text);
}
}
return trim ($text);
}
}
echo Slimdown::render ("# Title
And *now* [a link](http://www.google.com) to **follow** and [another](http://yahoo.com/).
* One
* Two
* Three
## Subhead
One **two** three **four** five.
One __two__ three _four_ five __six__ seven _eight_.
1. One
2. Two
3. Three
More text with `inline($code)` sample.
> A block quote
> across two lines.
More text...");
Origin https://gist.github.com/jbroadway/2836900

How can I add page numbers to PDFKit generated PDFs?

I have multiple pages generated using PDFKit. How can I add page numbers to the bottom?
PDFKit.configure do |config|
config.default_options = {
header_right: "Page [page] of [toPage]"
}
end
kit = PDFKit.new(body_html)
Read all detailed documentation here:
http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html
PDFKit is just a wrap up for wkhtmltopdf application that is written in C.
you need to specify a footer like this:
kit = PDFKit.new(your_html_content_for_pdf, :footer_html => "#{path_to_a_footer_html_file}")
then in the footer file have this:
<html>
<head>
<script type="text/javascript">
function subst() {
var vars={};
var x=document.location.search.substring(1).split('&');
for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
for(var i in x) {
var y = document.getElementsByClassName(x[i]);
for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
}
}
</script>
</head>
<body style="margin: 0;" onload="subst();">
Page <span class="page"></span> of <span class="topage"></span>
</body>
</html>
elements of classes 'frompage','topage','page','webpage','section','subsection','subsubsection' will get substituted with the appropriate data
I did page number with PDFKit, just by adding this:
%meta{:name => 'pdfkit-footer_right', :content => "[page]"}
in my haml file, in my RoR project.
For some weird reason, ( perhaps because I'm using slim ) - I have to use single quotes around the content, instead of double quotes - or else it attempts to escape the brackets and raw text "[page]" shows up, so try single quotes if you run into this issue with your pages.

Resources