TCPDF Custom page size - tcpdf

This example on tcpdf's website shows how to use page formats like A4, A5 etc, but how do I set tcpdf to use custom sizes like 175mm x 266 mm?
Solutions appreciated.

No editing of the class is require... tcpdf doesn't accept a width/length parameter, it just accepts two lengths and determines which is which using the layout (either Portrait or Landscape)
$pageLayout = array($width, $height); // or array($height, $width)
$pdf = new TCPDF('p', 'pt', $pageLayout, true, 'UTF-8', false);

Go to /config/tcpdf_config.php and around line 117, modify the line:
define ('PDF_PAGE_FORMAT', 'A4');
by
define ('PDF_PAGE_FORMAT', 'LETTER');
It is important to put "LETTER" in uppercase, you can see all possible values in this file: tcpdf/include/tcpdf_static.php.

On the newer TCPDF version you can define the page size in multiple ways:
All standard page formats are already defined (more than 300 types).
You can simply define a page size by defining an array with 2 numbers: width, height (regardless the page orientation).
Alternatively, you can define advanced page details (MediaBox, Cropbox, BleedBox, TrimBox, ArtBox) as explained on the documentation of the setPageFormat() method at http://www.tcpdf.org.
Check also the default examples no. 28 and 60 at http://www.tcpdf.org.

The truth, now you can solve it like this.
//AddPage [P(PORTRAIT),L(LANDSCAPE)],FORMAT(A4-A5-ETC)
$pdf->AddPage('P','A5');
Source:
https://tcpdf.org/examples/example_028/

// 8.5 X 13 inches paper (8.5, 13)
// Convert inches to mm (215.9, 330.2)
$pdf = new Pdf('P', 'mm', array(215.9, 330.2), true, 'UTF-8', false);

Edit tcpdf.php and add a new page type or modify an existing type to your page size.

The above answer won't work for me, so I add my solution here - from http://www.tcpdf.org/examples/example_060.phps, change urx, ury for your purpose
// set page format (read source code documentation for further information)
// MediaBox - width = urx - llx 210 (mm), height = ury - lly = 297 (mm) this is A4
$page_format = array(
'MediaBox' => array ('llx' => 0, 'lly' => 0, 'urx' => 210, 'ury' => 297),
//'CropBox' => array ('llx' => 0, 'lly' => 0, 'urx' => 210, 'ury' => 297),
//'BleedBox' => array ('llx' => 5, 'lly' => 5, 'urx' => 205, 'ury' => 292),
//'TrimBox' => array ('llx' => 10, 'lly' => 10, 'urx' => 200, 'ury' => 287),
//'ArtBox' => array ('llx' => 15, 'lly' => 15, 'urx' => 195, 'ury' => 282),
'Dur' => 3,
'trans' => array(
'D' => 1.5,
'S' => 'Split',
'Dm' => 'V',
'M' => 'O'
),
'Rotate' => 90,
'PZ' => 1,
);
// Check the example n. 29 for viewer preferences
// add first page ---
$pdf->AddPage('P', $page_format, false, false);

Related

Convert input sequence of array of hashes in and represent via grape entity

This is a 2 part question
A newbie to activerecord/Rails.
Once I execute the below activerecord query, I get
results = A.joins(:b).group(:id, :status).count
this result, now I want to present the results using an entity by postprocessing the output from
{[1, "action1"]=>2, [1, "action2"]=>2, [1, "action3"]=>1, [2, "action3"]=>2}
to
[{'id' => 1, 'action1' => 2, 'action2' => 2, 'action3' => 1}, {'id'=>2, 'action3' => 2, 'action1' => 0, 'action2' => 0} ]
(In the expected output's second hash, I added action1 => 0 and action2 => 0, because 0 should be default value.)
How to achieve the above output? I am unsure if the output of the query can be presented without postprocessing itself.
So far I tried
summaries.map {|k,v| {k[0] => {k[1] => v}}}.reduce {|acc, h| (acc || {}).deep_merge(h)}
need to make changes to the above map-reduce code to get expected result.
The expected response should look like the below, hence I am focussing on post processing the output of the query.
[
{ 'id' => value
'action1' => count,
'action1' => count,
'action1' => count
},
{
# same structure as above
}
]
I am trying to expose for example, only the id field in rails console but hitting the error
class klassEntity < Grape::Entity
expose :id
end
When I tried
klassEntity.represent([{'id' => 1, 'action1' => 2, 'action2' => 2, 'action3' => 1}, {'id'=>2, 'action3' => 2, 'action1' => 0, 'action2' => 0} ])
this failed with (Object doesn't support #inspect)
What am i doing wrong?
Update
I got this working by constructing a list of arrays from current output of
summaries.map {|k,v| {k[0] => {k[1] => v}}}.reduce {|acc, h| (acc || {}).deep_merge(h)}
and each array element contains a hash of symbols. This worked in rails console as well.
I am wondering if there is an optimal way to get here.
Find here an option using just the standard library.
I'm using map but with object (Enumerator#with_object) where the object is a Hash#new with a block given to get an empty hash as value to call Hash#merge! on it:
summaries = {[1, "action1"]=>2, [1, "action2"]=>2, [1, "action3"]=>1, [2, "action3"]=>2}
summaries.map.with_object(Hash.new {|h, k| h[k] = {}}){|(v, k), h| h[v.first].merge!({v.last => k})}
The result:
#=> {1=>{"action1"=>2, "action2"=>2, "action3"=>1}, 2=>{"action3"=>2}}

How to use Axlsx:NumFmt?

How do use Alxsx:NumFmt class?
I need to use this class to format currency values (positive and negative values)
I found some documentation for this class here - https://www.rubydoc.info/github/randym/axlsx/Axlsx/NumFmt
But there are no code samples available. Please help me on how to use this class.
Current Code:
currency_format_code = '$#,##0_;[Red]($#,##0_)'
#default_style = wb.styles.add_style(:format_code => currency_format_code,
:sz => 10, :font_name => "Arial",
:alignment => {:horizontal => :right})
#italics_style = wb.styles.add_style(:format_code => currency_format_code,
:sz => 10, :font_name => "Arial Narrow", :i => true,
:alignment => {:horizontal => :right})
row_style = [nil, nil, nil, #default_left_style] + ([#default_style] * 25)
sheet.add_row[nil, nil, nil, day1, day2, day3,
day4, day5, day6, day7, day8, day9,
day10, day11, day12, day13, day14,
day15, day16, day17, day18, day19,
day20, day21, day22, day23, day24,
day25], :style => row_style
I am not sure you can make this more performant than what you already have. This issue is that the style is applied to each cell in the row individually array_to_cells
Excerpt:
def array_to_cells(values, options={})
DataTypeValidator.validate :array_to_cells, Array, values
types, style, formula_values = options.delete(:types), options.delete(:style), options.delete(:formula_values)
values.each_with_index do |value, index|
options[:style] = style.is_a?(Array) ? style[index] : style if style
options[:type] = types.is_a?(Array) ? types[index] : types if types
options[:formula_value] = formula_values[index] if formula_values.is_a?(Array)
self[index] = Cell.new(self, value, options)
end
end
So as you can see it loops through all 28 cells in the row and looks up the style that should be applied for each then creates a new Cell with that style. Which is probably where the degradation is coming from.
Late to the party: To use the NumFmt numbers you add them to your style not using format_code, but the num_fmt option:
number_style = p.workbook.styles.add_style({
num_fmt: 2,
alignment: { horizontal: :center, :vertical => :center},
border: { color: "000000", style: :thin},
bg_color: "F2F2F2"
})

Prawn/PDF: Multiple formats/text on one line?

When I try the following code:
text "Hello "
text "World"
They render Hello on top of World instead of World right after Hello. I have some complicated formatting (highlighting, different font sizes etc) on text that I need on one line. I know that the :inline_formatting option exists but it seems this is too complicated to use that option.
I have the following code:
highlight_callback.rb:
class HighlightCallback
def initialize(options)
#color = options[:color]
#document = options[:document]
end
def render_behind(fragment)
original_color = #document.fill_color
#document.fill_color = #color
#document.fill_rectangle(fragment.top_left,
fragment.width,
fragment.height)
#document.fill_color = original_color
end
end
order.pdf.prawn:
highlight = HighlightCallback.new(:color => 'ffff00', :document => self)
#code....
text "Authorized Signature: "
formatted_text [{:text => "_" * 15, :callback => highlight }], :size => 20
which is producing the attached image. How can I get the signature line on the same level as the text?
Ruby 2.5.1
Rails 5.2.0
It's enough to change method text to text_box, i.e.:
bounding_box([0, cursor], width: 540, height: 40) do
stroke_color 'FFFF00'
stroke_bounds
date = 'Date: '
text_box date, style: :bold
text_box DateTime.now.strftime('%Y/%m/%d'), at: [bounds.left + width_of(date), cursor]
text_box "Signature ________________", align: :right
end
Example:
To place text at a exact position you can use text_box with the option :at.
You can get the width of your text with pdf.width_of(str) (use the same style optione :size etc. otherwise it will use the default settings to calculate)

Ruby - how to replace key in a hash by a key from different one?

I have this hash:
CARS = {"Audi" => 0,
"BMW" => 1,
...}
And this output from ActiveRecord (#top_cars):
{1=>18, 0=>17, 3=>13, 5=>10, 2=>5, 4=>1}
How do I replace the keys from #top_cars by the car names from CARS?
Thank you
EDIT:
So the desired output would be like {"BMW"=>18, "Audi"=>17, "Renault"=>13, "Mercedes"=>10, "Ford"=>5, "Porsche"=>1}
This would do the trick:
#top_cars.map {|key, value| [CARS.key(key), value]}.to_h
possible solution:
#top_cars.inject({}) {|memo, (key,value)| memo.merge(CARS.key(key) => value)}
You could merge cars with itself:
cars = { "Audi" => 0,
"Mercedes" => 1,
"Ford" => 2,
"Renault" => 3,
"BMW" => 4,
"Porsche" => 5
}
top_cars = {1=>18, 0=>17, 3=>13, 5=>10, 2=>5, 4=>1}
cars.merge(cars) { |*,n| top_cars[n] }
#=> {"Audi"=>17, "Mercedes"=>18, "Ford"=>5, "Renault"=>13, "BMW"=>1, "Porsche"=>10}
This uses the form of Hash#merge where a block is employed to determine the values of keys that are present in both hashes being merged, which here is all the keys.

Table cell border

This is the 2x2 table I need to generate:
r1c1 r1c2
r2c1 r2c1
----
In other words I should print the bottom border of the bottom right cell. This is my code:
show.pdf.prawn
#This is a two dimensional array:
my_array = [["r1c1","r1c2"],["r2c1",Prawn::Table::Cell.new(:text => "r2c2", :border_width => 1 , :borders => :bottom)]]
#Table
pdf.table my_array, :border_width => 0
Well, with this code I have a 2x2 table with no borders!
Has someone any tip?
Here one solution better known as workaround:
#This is a two dimensional array:
my_array = [["r1c1","r1c2"],["r2c1",Prawn::Table::Cell.new(:text => "r2c2", :border_width => 1 , :borders => [:bottom])]]
#Table
pdf.table my_array,
#:headers => ["h1","h2"],
:border_style => :underline_header
Omitting headers => ["h1","h2"] you avoid the underlined header.

Resources