Regex over a html page - regex

Hello I'm trying to select 4 values from a html page (static page of a printer) The thing is i have some issues succeeding. I have some attempts all fail could you guys help me pls:
hole page = http://pastebin.com/e7eKAV0x
code of intresst:
<tr>
<td>
Yellow Cartridge
<br>
Order 305A (CE412A)
</td>
<td class="alignRight valignTop">
40%
†
</td>
</tr>
(Please use inspect / check the page) I need the 40% value from 4 different filds(printer colors). When color is out --
My last try:
public void buildCartigesAndValue(String ipString) throws IOException {
LOGGER.log(Level.INFO, "Starting mining over IP " + ipString);
String context = getUrlSource(ipString);
System.out.println(context);
urlPart = "/info_colorUsageJobLog.html?tab=Status&menu=ColorUsageLog";
if (context.contains("HP Color LaserJet CP2025dn") || context.contains("HP Color LaserJet CM2320nf MFP")) {
LOGGER.log(Level.INFO, "PRINTER TYPE ======= HP Color LaserJet CP2025dn");
regexColorContent = "\\w+\\W{1}Cartridge (?<!Printer)";
regexTagContent = "(<td{1}>)([^<]{1}[^.{20}][^ ].*?)(</td>)";
}
else if (context.contains("HP LaserJet 400 color M451dw")){
LOGGER.log(Level.INFO, "PRINTER TYPE ======= HP LaserJet 400 color M451dw");
regexColorContent = "\\w+\\W{1}Cartridge (?<!Printer)";
regexTagContent = "Cartridge.{50}";
}
List<Integer> vals = findCartegisProcentr(context);
List<String> colors = findCartigesColor(context);
for (int i = 0; i < colors.size(); i++) {
if (colors.get(i).contains("Printer")) {
continue;
}
System.out.println(colors.get(i));
addNewColorVal(colors.get(i), vals.get(i));
}
LOGGER.log(Level.INFO, "Stopping sucessfully ---- MAP ---- " + this.colorAmountMap.toString());
}
public List<Integer> findCartegisProcentr(String context) {
List<Integer> vals = new ArrayList<>();
regexValContent = "\\d{2}|-{2}"; // FOR PARTICULAR THE VALUES
Pattern patternTagContent = Pattern.compile(regexTagContent);
Matcher matcherTagContent = patternTagContent.matcher(context);
Pattern patternValContent = Pattern.compile(regexValContent);
while (matcherTagContent.find()) {
Matcher matcherValContent = patternValContent
.matcher(matcherTagContent.group());
matcherValContent.find();
try {
vals.add(Integer.parseInt(matcherValContent.group()));
} catch (Exception e) {
vals.add(0);
}
}
return vals;
}

Related

Create multiple DMN using Java Camunda Springboot starter

I would like to create a Java service that would build a Camunda DMN via code. I'm using camunda-springboot-starter dependency and I'm able to generate the DMN DecisionTable and output of one decision is used in another. I'm using InformationRequirement for same but when I write the model to file and open that file in modeler the arrow is not coming for information requirement and after deploying the decision is not able to get that output.
<
public String generateDMN(String name, String title) throws FileNotFoundException {
DmnModelInstance modelInstance = initializeEmptyDmnModel();
Decision decision = modelInstance.newInstance(Decision.class);
decision.setId(title);
decision.setName(name);
modelInstance.getDefinitions().addChildElement(decision);
List<String[]> rules = new ArrayList<>();
try (CSVReader reader = new CSVReader(new FileReader("/Users/rahulnehete/IdeaProjects/java-rules-engine/src/main/resources/file.csv"))) {
rules = reader.readAll();
} catch (Exception e) {
log.error("Error reading CSV file ", e);
}
DecisionTable decisionTable = modelInstance.newInstance(DecisionTable.class);
decisionTable.setId("DecisionTable_"+name+"_"+title);
decisionTable.setHitPolicy(HitPolicy.COLLECT);
decision.addChildElement(decisionTable);
Decision decision2 = modelInstance.newInstance(Decision.class);
decision2.setId(title + "_2");
decision2.setName(name + "_2");
modelInstance.getDefinitions().addChildElement(decision2);
DecisionTable decisionTable2 = modelInstance.newInstance(DecisionTable.class);
decisionTable2.setId("DecisionTable_"+name+"_"+title+"_2");
decisionTable2.setHitPolicy(HitPolicy.COLLECT);
decision2.addChildElement(decisionTable2);
InformationRequirement infoRequirement = modelInstance.newInstance(InformationRequirement.class, "info1");
decision2.getInformationRequirements().add(infoRequirement);
infoRequirement.setRequiredDecision(decision);
String[] header = rules.remove(0);
String[] varTypes = rules.remove(0);
String[] variables = rules.remove(0);
Long numOfInputs = Arrays.stream(header).filter(k -> k.equalsIgnoreCase("input")).count();
Long numOfOutputs = Arrays.stream(header).filter(k -> k.equalsIgnoreCase("output")).count();
for(int i=0; i<numOfInputs; i++) {
Input ip = generateElement(modelInstance, Input.class, "Input_"+i);
InputExpression inputExpression = generateElement(modelInstance, InputExpression.class);
Text text = modelInstance.newInstance(Text.class);
inputExpression.setText(text);
inputExpression.setTypeRef(varTypes[i]);
ip.setLabel("Input " + i);
ip.setCamundaInputVariable(variables[i]);
ip.setInputExpression(inputExpression);
decisionTable.addChildElement(ip);
}
for(int i=numOfInputs.intValue(); i<=numOfOutputs; i++) {
Output op = generateElement(modelInstance, Output.class, "Output_"+i);
op.setLabel("Output " + i);
op.setName(variables[i]);
op.setTypeRef(varTypes[i]);
decisionTable.addChildElement(op);
}
for(int i = 1; i<rules.size(); i++) {
String[] rule = rules.get(i);
Rule dmnRule = createRule(modelInstance, numOfInputs.intValue(), numOfOutputs.intValue(), rule);
decisionTable.addChildElement(dmnRule);
log.info("Rule {} added", i);
}
Input ip = generateElement(modelInstance, Input.class, "Input_A");
InputExpression inputExpression = generateElement(modelInstance, InputExpression.class);
Text text = modelInstance.newInstance(Text.class);
inputExpression.setText(text);
inputExpression.setTypeRef("string");
ip.setLabel("Input A");
ip.setCamundaInputVariable("minPlafond");
ip.setInputExpression(inputExpression);
decisionTable2.addChildElement(ip);
Output op = generateElement(modelInstance, Output.class, "Output_A");
op.setLabel("Output A");
op.setName("FinalOutput");
op.setTypeRef("string");
decisionTable2.addChildElement(op);
// TODO: variable names
String[] rule = new String[] {"-", "$(minPlafond + " + "\"_Success\")"};
Rule dmnRule = createRule(modelInstance, 1, 1, rule);
decisionTable2.addChildElement(dmnRule);
log.info("Rule {} added", "new");
Dmn.validateModel(modelInstance);
try {
FileOutputStream fos = null;
fos = new FileOutputStream(name + "_" + title + ".dmn");
Dmn.writeModelToStream(fos, modelInstance);
fos.close();
} catch (IOException e) {
log.error("Error writing model instance ", e);
return REConstants.FAILED;
}
return "DMN GENERATED";
}
private DmnModelInstance initializeEmptyDmnModel() {
DmnModelInstance dmnModel = Dmn.createEmptyModel();
Definitions definitions = generateNamedElement(dmnModel, Definitions.class, "definitions", "definitions");
definitions.setNamespace(DmnModelConstants.CAMUNDA_NS);
dmnModel.setDefinitions(definitions);
return dmnModel;
}
private <E extends DmnElement> E generateElement(DmnModelInstance modelInstance, Class<E> elementClass, String id) {
E element = modelInstance.newInstance(elementClass);
element.setId(id);
return element;
}
private <E extends NamedElement> E generateNamedElement(DmnModelInstance modelInstance, Class<E> elementClass, String name, String id) {
E element = generateElement(modelInstance, elementClass, id);
element.setName(name);
return element;
}
private <E extends DmnElement> E generateElement(DmnModelInstance modelInstance, Class<E> elementClass) {
String generatedId = elementClass.getSimpleName() + UUID.randomUUID();
return generateElement(modelInstance, elementClass, generatedId);
}
private Rule createRule(DmnModelInstance dmnModelInstance, int numberOfInputs, int numberOfOutputs, String[] ruleInput) {
Rule rule = dmnModelInstance.newInstance(Rule.class);
for(int i=0; i<numberOfOutputs; i++) {
OutputEntry outputEntry = createOutputEntry(dmnModelInstance, ruleInput[numberOfInputs + i]);
rule.getOutputEntries().add(outputEntry);
}
for (int i = 0; i < numberOfInputs; i++) {
InputEntry inputEntry = createInputEntry(dmnModelInstance, ruleInput[i]);
rule.getInputEntries().add(inputEntry);
}
return rule;
}
private InputEntry createInputEntry(DmnModelInstance dmnModelInstance, String expression) {
Text text = dmnModelInstance.newInstance(Text.class);
text.setTextContent(expression);
InputEntry inputEntry = dmnModelInstance.newInstance(InputEntry.class);
inputEntry.setText(text);
return inputEntry;
}
private OutputEntry createOutputEntry(DmnModelInstance dmnModelInstance, String expression) {
Text text = dmnModelInstance.newInstance(Text.class);
text.setTextContent(expression);
OutputEntry outputEntry = dmnModelInstance.newInstance(OutputEntry.class);
outputEntry.setText(text);
return outputEntry;
}
}
You implemented the decisions, decisions table, input and output as well as info requirement correctly on model level (xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/"). (Dmn.writeModelToFile(new File("src/main/resources/my.dmn"), modelInstance); is little more compact than writing the stream yourself.)
When you compare to a model created by the Modeler, you see that it uses additional namespaces such as xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/". This namespaces defines the diagram information separately from the model, e.g:
<dmndi:DMNDI>
<dmndi:DMNDiagram id="DMNDiagram_12sfwjw">
<dmndi:DMNShape id="DMNShape_1m8k4eq" dmnElementRef="Decision1">
<dc:Bounds height="80" width="180" x="150" y="80" />
</dmndi:DMNShape>
<dmndi:DMNShape id="DMNShape_15h0omx" dmnElementRef="Decision2">
<dc:Bounds height="80" width="180" x="240" y="200" />
</dmndi:DMNShape>
<dmndi:DMNEdge id="DMNEdge_15fnvnh" dmnElementRef="InformationRequirement_0a97hay">
<di:waypoint x="330" y="200" />
<di:waypoint x="240" y="180" />
<di:waypoint x="240" y="160" />
</dmndi:DMNEdge>
</dmndi:DMNDiagram>
</dmndi:DMNDI>
Unfortunately, the Camunda API currently offers no way of auto-generating or creating this diagram information.You would have to approach this a level lower with an XML library.
The model is executable without the diagram information. So, you will have a working model. Maybe that is acceptable and only if a human cares about the DRD it can be created manually?
An alternative would be to abandon the Java approach and try https://bpmn.io/toolkit/dmn-js/.

Performance Issue when retrieving transaction details from Quorum Blockchain

I have experienced performance issue when retrieving transaction details such as transaction originator and transaction recipient
from the Quorum blockchain.
The Javascript For loop and Web3.eth.contract(abi).at(address2).totalTransactions is used to retrieve transaction details and
then append to HTML table.
My performance problem is that the retrieval of few lines of transaction data from Quorum blockchain takes about 30 seconds.
Moreover, I am using web3-quorum#0.1.1 and quorum-js#0.3.0.
$('#get-tran').click(() => {
// Get Tran History
var tranId = 0;
let w2Contract=web3w2.eth.contract(abi).at(address2);
let tottr = w2Contract.totalTransactions();
//Clear the old table content first
$("#t02 tr").remove();
var i=0;
for (i = 0; i <= w2Contract.totalTransactions()-1; i++) {
tranId = i;
let tranHash = w2Contract.transactionIDs(i);
let trDetails1 = w2Contract.transactions(tranHash);
console.log(`Tran details ${trDetails1}`);
console.log(`Tran Detail 1: ${trDetails1[1]}`);
console.log(`Tran Detail 2: ${trDetails1[2]}`);
console.log(`Tran Detail 0: ${trDetails1[0]}`);
var tableRef = document.getElementById('t02').getElementsByTagName('tbody')[0];
// Insert a row at the end of the table
let newRow = tableRef.insertRow(-1);
// Insert a cell in the row at index 0
let newCell = newRow.insertCell(0);
// Append a text node to the cell
let newText = document.createTextNode(`${tranId}`);
newCell.appendChild(newText);
// Insert a cell in the row at index 1
let newCell1 = newRow.insertCell(1);
// Append a text node to the cell
let newText1 = document.createTextNode(`${trDetails1[1]}`);
console.log(`newText1 at index 1 ${newText1}`);
// w2 > w1
if ((trDetails1[1] == '0xf9a2cb34b6b5fd7a2ac0c2e9b2b9406d6daffbd4') &&
(trDetails1[2] == '0x180893a0ec847fa8c92786791348d7d65916acbb')) {
newText1.textContent = 'Stock In'
} else if
(trDetails1[1] == '0x180893a0ec847fa8c92786791348d7d65916acbb') {
newText1.textContent = 'Pier Company'
} else if (trDetails1[1] == '0xf9a2cb34b6b5fd7a2ac0c2e9b2b9406d6daffbd4') {
newText1.textContent = 'Warehouse Company'
}
newCell1.appendChild(newText1);
// Insert a cell in the row at index 2
let newCell2 = newRow.insertCell(2);
// Append a text node to the cell
let newText2 = document.createTextNode(`${trDetails1[2]}`);
console.log(`newText1 at index 2 ${newText1}`);
if (trDetails1[2] == '0xf9a2cb34b6b5fd7a2ac0c2e9b2b9406d6daffbd4') {
newText2.textContent = 'Warehouse Company'
}
if (trDetails1[2] == '0x180893a0ec847fa8c92786791348d7d65916acbb') {
newText2.textContent = 'Pier Company'
}
if (trDetails1[2] == '0xc8f717ba9593dc9d45c4518cf444d2cbd08af24d') {
newText2.textContent = 'Removal'
}
newCell2.appendChild(newText2);
// Insert a cell in the row at index 3
let newCell3 = newRow.insertCell(3);
// Append a text node to the cell
let newText3 = document.createTextNode(`${trDetails1[0]}`);
console.log(`newText3 at index 3 ${newText3}`);
newCell3.appendChild(newText3);
// Insert a cell in the row at index 4
let newCell4 = newRow.insertCell(4);
// Append a text node to the cell
let newText4 = document.createTextNode(`${trDetails1[3]}`);
console.log(`newText1 at index 4 ${newText4}`);
if (trDetails1[3] ) {
newText4.textContent = 'Confirmed'
} else {
newText4.textContent = 'Pending'
}
newCell4.appendChild(newText4);
}
});

Parsing tags in string

I'm trying to parse a string with custom tags like this
[color value=0x000000]This house is [wave][color value=0xFF0000]haunted[/color][/wave].
I've heard about ghosts [shake]screaming[/shake] here after midnight.[/color]
I've figured out what regexps to use
/\[color value=(.*?)\](.*?)\[\/color\]/gs
/\[wave\](.*?)\[\/wave\]/gs
/\[shake\](.*?)\[\/shake\]/gs
But the thing is - I need to get correct ranges (startIndex, endIndex) of those groups in result string so I could apply them correctly. And that's where I feel completely lost, because everytime I replace tags there's always a chance for indexes to mess up. It gets espesically hard for nested tags.
So input is a string
[color value=0x000000]This house is [wave][color value=0xFF0000]haunted[/color][/wave].
I've heard about ghosts [shake]screaming[/shake] here after midnight.[/color]
And in output I want to get something like
Apply color 0x000000 from 0 to 75
Apply wave from 14 to 20
Apply color 0xFF0000 from 14 to 20
Apply shake from 46 to 51
Notice that's indices match to result string.
How do I parse it?
Unfortunately, I'm not familiar with ActionScript, but this C# code shows one solution using regular expressions. Rather than match specific tags, I used a regular expression that can match any tag. And instead of trying to make a regular expression that matches the whole start and end tag including the text in between (which I think is impossible with nested tags), I made the regular expression just match a start OR end tag, then did some extra processing to match up the start and end tags and remove them from the string keeping the essential information.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
class Program
{
static void Main(string[] args)
{
string data = "[color value=0x000000]This house is [wave][color value=0xFF0000]haunted[/color][/wave]. " +
"I've heard about ghosts [shake]screaming[/shake] here after midnight.[/color]";
ParsedData result = ParseData(data);
foreach (TagInfo t in result.tags)
{
if (string.IsNullOrEmpty(t.attributeName))
{
Console.WriteLine("Apply {0} from {1} to {2}", t.name, t.start, t.start + t.length - 1);
}
else
{
Console.WriteLine("Apply {0} {1}={2} from {3} to {4}", t.name, t.attributeName, t.attributeValue, t.start, t.start + t.length - 1);
}
Console.WriteLine(result.data);
Console.WriteLine("{0}{1}\n", new string(' ', t.start), new string('-', t.length));
}
}
static ParsedData ParseData(string data)
{
List<TagInfo> tagList = new List<TagInfo>();
Regex reTag = new Regex(#"\[(\w+)(\s+(\w+)\s*=\s*([^\]]+))?\]|\[(\/\w+)\]");
Match m = reTag.Match(data);
// Phase 1 - Collect all the start and end tags, noting their position in the original data string
while (m.Success)
{
if (m.Groups[1].Success) // Matched a start tag
{
tagList.Add(new TagInfo()
{
name = m.Groups[1].Value,
attributeName = m.Groups[3].Value,
attributeValue = m.Groups[4].Value,
tagLength = m.Groups[0].Length,
start = m.Groups[0].Index
});
}
else if (m.Groups[5].Success)
{
tagList.Add(new TagInfo()
{
name = m.Groups[5].Value,
tagLength = m.Groups[0].Length,
start = m.Groups[0].Index
});
}
m = m.NextMatch();
}
// Phase 2 - match end tags to start tags
List<TagInfo> unmatched = new List<TagInfo>();
foreach (TagInfo t in tagList)
{
if (t.name.StartsWith("/"))
{
for (int i = unmatched.Count - 1; i >= 0; i--)
{
if (unmatched[i].name == t.name.Substring(1))
{
t.otherEnd = unmatched[i];
unmatched[i].otherEnd = t;
unmatched.Remove(unmatched[i]);
break;
}
}
}
else
{
unmatched.Add(t);
}
}
int subtractLength = 0;
// Phase 3 - Remove tags from the string, updating start positions and calculating length in the process
foreach (TagInfo t in tagList.ToArray())
{
t.start -= subtractLength;
// If this is an end tag, calculate the length for the corresponding start tag,
// and remove the end tag from the tag list.
if (t.otherEnd.start < t.start)
{
t.otherEnd.length = t.start - t.otherEnd.start;
tagList.Remove(t);
}
// Keep track of how many characters in tags have been removed from the string so far
subtractLength += t.tagLength;
}
return new ParsedData()
{
data = reTag.Replace(data, string.Empty),
tags = tagList.ToArray()
};
}
class TagInfo
{
public int start;
public int length;
public int tagLength;
public string name;
public string attributeName;
public string attributeValue;
public TagInfo otherEnd;
}
class ParsedData
{
public string data;
public TagInfo[] tags;
}
}
The output is:
Apply color value=0x000000 from 0 to 76
This house is haunted. I've heard about ghosts screaming here after midnight.
-----------------------------------------------------------------------------
Apply wave from 14 to 20
This house is haunted. I've heard about ghosts screaming here after midnight.
-------
Apply color value=0xFF0000 from 14 to 20
This house is haunted. I've heard about ghosts screaming here after midnight.
-------
Apply shake from 47 to 55
This house is haunted. I've heard about ghosts screaming here after midnight.
---------
Let me show you a parsing method that you can apply not only to the case above, but to every case with a pattern cutting through the case. This method is not limited to the terms - color, wave, shake.
private List<Tuple<string, string>> getVals(string input)
{
List<Tuple<string, string>> finals = new List<Tuple<string,string>>();
// first parser
var mts = Regex.Matches(input, #"\[[^\u005D]+\]");
foreach (var mt in mts)
{
// has no value=
if (!Regex.IsMatch(mt.ToString(), #"(?i)value[\n\r\t\s]*="))
{
// not closing tag
if (!Regex.IsMatch(mt.ToString(), #"^\[[\n\r\t\s]*\/"))
{
try
{
finals.Add(new Tuple<string, string>(Regex.Replace(mt.ToString(), #"^\[|\]$", "").Trim(), ""));
}
catch (Exception es)
{
Console.WriteLine(es.ToString());
}
}
}
// has value=
else
{
try
{
var spls = Regex.Split(mt.ToString(), #"(?i)value[\n\r\t\s]*=");
finals.Add(new Tuple<string, string>(Regex.Replace(spls[0].ToString(), #"^\[", "").Trim(), Regex.Replace(spls[1].ToString(), #"^\]$", "").Trim()));
}
catch (Exception es)
{
Console.WriteLine(es.ToString());
}
}
}
return finals;
}
I also have an experience parsing JSON with a single regular expression. If you wonder what it is, visit my blog www.mysplitter.com .

Sitecore change rendering datasource

Hello I would like create special page for private use for where i will be have possibility to change data source value for each rendering item.
I have created next code, but it dos't save any changes to items.
SC.Data.Database master = SC.Configuration.Factory.GetDatabase("master");
SC.Data.Items.Item itm = master.GetItem(tbPath.Text);
if (itm != null)
{
// Get the sublayout to update
//string sublayout_name = txtSublayout.Text.Trim();
//if (!string.IsNullOrEmpty(sublayout_name))
{
// Get the renderings on the item
RenderingReference[] refs = itm.Visualization.GetRenderings(SC.Context.Device, true);
if (refs.Any())
{
//var data = refs.Select(d=>d);
//refs[0].Settings.DataSource
var sb = new StringBuilder();
using (new SC.SecurityModel.SecurityDisabler())
{
itm.Editing.BeginEdit();
foreach (var d in refs)
{
if (d.Settings.DataSource.Contains("/sitecore/content/Site Configuration/"))
{
var newds = d.Settings.DataSource.Replace("/sitecore/content/Site Configuration/", "/sitecore/content/Site Configuration/" + tbLanguage.Text + "/");
// sb.AppendLine(string.Format("{0} old: {1} new: {2}<br/>", d.Placeholder, d.Settings.DataSource, newds));
d.Settings.DataSource = newds;
}
}
itm.Editing.EndEdit();
}
//lblResult.Text = sb.ToString();
}
}
}
how I can change data source ?
thanks
You're mixing up two different things in Sitecore here.
The datasource that is assigned to a rendering at run-time, when Sitecore is rendering a page
The datasource that is assigned to the presentation details of an item
The simplest approach to achieve what I think you're trying to achieve, would be this.
Item itm = database.GetItem("your item");
string presentationXml = itm["__renderings"];
itm.Editing.BeginEdit();
presentationXml.Replace("what you're looking for", "what you want to replace it with");
itm.Editing.EndEdit();
(I've not compiled and run this code, but it should pretty much work as is)
You are not saving the changes to the field.
Use the LayoutDefinitation class to parse the layout field, and foreach all the device definition, and rendering definitions.
And finaly commit the LayoutDifinition to the layout field.
SC.Data.Items.Item itm = master.GetItem(tbPath.Text);
var layoutField = itm.Fields[Sitecore.FieldIDs.LayoutField];
LayoutDefinition layout = LayoutDefinition.Parse(layoutField.Value);
for (int i = 0; i < layout.Devices.Count; i++)
{
DeviceDefinition device = layout.Devices[i] as DeviceDefinition;
for (int j = 0; j < device.Renderings.Count; j++)
{
RenderingDefinition rendering = device.Renderings[j] as RenderingDefinition;
rendering.Datasource = rendering.DataSource.Replace("/sitecore/content/Site Configuration/",
"/sitecore/content/Site Configuration/" + tbLanguage.Text + "/");
}
}
itm.Editing.BeginEdit();
var xml =layout.ToXml()
layoutField.Value = xml;
itm.Editing.EndEdit();
The code is not testet, but are changed from something i have in production to replace datasources on a copy event
If any one looking for single line Linq : (Tested)
var layoutField = item.Fields[Sitecore.FieldIDs.LayoutField];
if (layoutField != null)
{
var layout = LayoutDefinition.Parse(layoutField.Value);
if (layout != null)
{
foreach (var rendering in layout.Devices.Cast<DeviceDefinition>()
.SelectMany
(device => device.Renderings.Cast<RenderingDefinition>()
.Where
(rendering => rendering.ItemID == "RenderingYoulooking")))
{
rendering.Datasource = "IDYouWantToInsert";
}
layoutField.Value = layout.ToXml();
}
}

fpdf printing cell table vertically

I have this data from mysql database:
Using this code:
<?php
require('fpdf/fpdf.php');
require("aacfs.php");
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial', '', 8);
$locquery=mysql_query("select * from ptr where reservno = '0000187' group by ptr_id asc") or die(mysql_error());
while($locrow=mysql_fetch_array($locquery))
{
$pdf->Cell(30, 6, $locrow['location'], 1, 0, 'C');
}
$pdf->Ln();
$fquoquery=mysql_query("select distinct fquo_id as 'fquo_id' from passengers where reservno = '0000187' group by pass_id asc") or die(mysql_error());
while($fquorow=mysql_fetch_array($fquoquery))
{
$fquo=$fquorow['fquo_id'];
$passquery=mysql_query("select * from passengers where fquo_id = '$fquo' group by pass_id asc") or die(mysql_error());
while($passrow=mysql_fetch_array($passquery))
{
$pdf->Cell(30, 6, $passrow['pass_name'], 1, 0, 'C');
}
$pdf->Ln();
}
$pdf->Output();
?>
I'm trying to generate a pdf with this output:
But I'm having this wrong output instead:
How can I achieve the desired output using fpdf? Please help me out!
The best example i could give you on how to achieve this would be to adjust the following query and variables to meet your needs:
<?php
require('fpdf.php');
//Connect to your database
include("conectmysql.php");
//Create new pdf file
$pdf=new FPDF();
//Disable automatic page break
$pdf->SetAutoPageBreak(false);
//Add first page
$pdf->AddPage();
//set initial y axis position per page
$y_axis_initial = 25;
//print column titles
$pdf->SetFillColor(232,232,232);
$pdf->SetFont('Arial','B',12);
$pdf->SetY($y_axis_initial);
$pdf->SetX(25);
$pdf->Cell(30,6,'CODE',1,0,'L',1);
$pdf->Cell(100,6,'NAME',1,0,'L',1);
$pdf->Cell(30,6,'PRICE',1,0,'R',1);
$y_axis = $y_axis + $row_height;
//Select the Products you want to show in your PDF file
$result=mysql_query('select Code,Name,Price from Products ORDER BY Code',$link);
//initialize counter
$i = 0;
//Set maximum rows per page
$max = 25;
//Set Row Height
$row_height = 6;
while($row = mysql_fetch_array($result))
{
//If the current row is the last one, create new page and print column title
if ($i == $max)
{
$pdf->AddPage();
//print column titles for the current page
$pdf->SetY($y_axis_initial);
$pdf->SetX(25);
$pdf->Cell(30,6,'CODE',1,0,'L',1);
$pdf->Cell(100,6,'NAME',1,0,'L',1);
$pdf->Cell(30,6,'PRICE',1,0,'R',1);
//Go to next row
$y_axis = $y_axis + $row_height;
//Set $i variable to 0 (first row)
$i = 0;
}
$code = $row['Code'];
$price = $row['Price'];
$name = $row['Code'];
$pdf->SetY($y_axis);
$pdf->SetX(25);
$pdf->Cell(30,6,$code,1,0,'L',1);
$pdf->Cell(100,6,$name,1,0,'L',1);
$pdf->Cell(30,6,$price,1,0,'R',1);
//Go to next row
$y_axis = $y_axis + $row_height;
$i = $i + 1;
}
mysql_close($link);
//Send file
$pdf->Output();
?>