Generated PDF ignores some CSS & HTML - c#

My web application are showing a div including a QR-image and some text from a database. And with iTextSharp I generate this html-page to a PDF. This works great, the problem is that the PDF doesn't read some of the CSS. I've tried every possible way to use CSS ( some css and in an external file)
It looks good in the browser, but when it's generated to a PDF the only similarity is the background color. Nothing else. So I need to know if there's any possible way to change the position. This is how it looks on the web
|||
And this is how it looks like in the PDF
As you can see there's a huge difference. The text doesn't even show in the PDF. I can change height and width on the image, but not e.g. margin.
Here's the logic to create my PDF.
Byte[] bytes; // This byte array will hold the final PDF.
var cssText = File.ReadAllText(#"C:\Users\My_Name\documents\visual studio 2012\Projects\QR\QR\Content\CSS.css");
var htmlText = File.ReadAllText(#"C:\Users\My_Name\documents\visual studio 2012\Projects\QR\QR\WebForm1.aspx");
//Creating a stream that we can write to, - a memorystream in this case.
using (var memoryStream = new MemoryStream())
{
//iTextSharp Document which is an abstraction of a PDF but NOT a PDF.
using (var doc = new Document())
{
using (var writer = PdfWriter.GetInstance(doc, memoryStream))
{
doc.Open();
using (var memoryStreamCSS = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(cssText)))
{
using (var memoryStreamHTML = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(htmlText)))
{
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, memoryStreamHTML, memoryStreamCSS);
}
}
doc.Close();
}
}
bytes = memoryStream.ToArray();
}
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Testing.pdf");
File.WriteAllBytes(testFile, bytes);
}
And here's the html:
<form id="form1" runat="server">
<asp:Panel ID="Panel1" runat="server">
<div id="qr">
<div class="qrImage">
<img src="http://localhost:19859/Image/QrCode.jpg" id="qrImage" />
</div>
<div class="information">
<h1>
<asp:Label runat="server" ID="building"></asp:Label></h1>
<p class="productName prodInfo">
<asp:Label runat="server" ID="productName"></asp:Label>
</p>
<p class="prodInfo">
<asp:Label runat="server" ID="productInfo"></asp:Label>
</p>
<p class="prodInfo">
<asp:Label runat="server" ID="productSomething"></asp:Label>
</p>
<p class="prodInfo">
<asp:Label runat="server" ID="productPlace"></asp:Label>
</p>
</div>
</div>
</asp:Panel>
<asp:Button ID="btnExport" runat="server" Text="Export"
OnClick="btnExport_Click" />
</form>
And here's the code to generate the QR-code:
QRCodeEncoder encoder = new QRCodeEncoder();
Bitmap img = encoder.Encode(_qrLink); //Choose one special link to generate a QR-code from.
img.Save(#"C:\Users\My_Name\Documents\visual studio 2012\Projects\QR\QR\Image\QrCode.jpg", ImageFormat.Jpeg);
Here's my CSS
body { font-family: arial;
width: 110mm;
height: 55mm;
}
table {
background-color: #e5daa2;
width: 100mm;
height: 50mm;
}
#qr {
background-color: #e5daa2;
width: 100mm;
height: 50mm;
margin-left: 10px;
-ms-border-radius: 10px;
border-radius: 10px;
}
.qrImage img {
margin-top: 10mm;
}
img {
width: 130px;
margin-left: 3mm;
margin-top: 10mm;
}
.information {
float: right;
margin-top: -38mm;
}
.prodInfo {
font-size: 11px;
margin-top: -32mm;
margin-left: -60mm;
}
.productName {
font-weight: bold;
font-size: 12px;
}

Related

C#:docx generated from html by open xml power tools throw pre release 2007

I'm writing code that get the content of Docx file as HTML by using open XML power tools and now I want to convert it back to another docx file. the step that gets contents as HTML works fine but when I generate the docx file from that HTML the file cannot be opened and throws this error
this file was created in a pre-release version of word 2007 and cannot
be opened in this version
the HTML generated from test docx is
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta
charset="UTF-8" />
<title>My Page Title</title>
<meta
name="Generator"
content="PowerTools for Open XML" />
<style>span { white-space: pre-wrap; }
p.pt-Normal {
line-height: 107.9%;
margin-bottom: 8pt;
text-align: justify;
font-family: ;
font-size: 11pt;
margin-top: 0;
margin-left: 0;
margin-right: 0;
}
span.pt-DefaultParagraphFont {
font-family: ;
font-size: 11pt;
font-style: normal;
font-weight: normal;
margin: 0;
padding: 0;
}
span.pt-DefaultParagraphFont-000000 {
font-family: Calibri;
font-size: 11pt;
font-style: normal;
font-weight: normal;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div>
<p
dir="rtl"
class="pt-Normal">‏<span
lang="fa-IR"
class="pt-DefaultParagraphFont">‏با سلام خدمت ‏</span><span
lang="fa-IR"
class="pt-DefaultParagraphFont">‏<<‏</span><span
class="pt-DefaultParagraphFont-000000">‎PERSONS.lname‎</span><span
lang="fa-IR"
class="pt-DefaultParagraphFont">‏>>‏</span><span
lang="fa-IR"
class="pt-DefaultParagraphFont">‏ ‏</span><span
lang="fa-IR"
class="pt-DefaultParagraphFont">‏<<‏</span><span
class="pt-DefaultParagraphFont-000000">‎PERSONS.fname‎</span><span
lang="fa-IR"
class="pt-DefaultParagraphFont">‏>>‏</span></p>
<p
dir="rtl"
class="pt-Normal">‏<span
lang="fa-IR"
class="pt-DefaultParagraphFont">‏مدیر محترم ‏</span><span
lang="fa-IR"
class="pt-DefaultParagraphFont">‏<<‏</span><span
class="pt-DefaultParagraphFont-000000">‎OFFICE.name‎</span><span
lang="fa-IR"
class="pt-DefaultParagraphFont">‏>>‏</span></p>
</div>
</body>
</html>
and my code to save the above html as docx is
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Create(dest_doc_path, WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
string htmlcontent = htmlTXT.Text;
using (Stream stream = mainPart.GetStream())
{
byte[] buf = (new UTF8Encoding()).GetBytes(htmlcontent);
stream.Write(buf, 0, buf.Length);
}
MessageBox.Show("DONE", "done", MessageBoxButton.OK);
}
The answer is simple. You must not insert HTML content into the MainDocumentPart because it is expected to contain a valid Open XML w:document element, e.g., as the following simplified one:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:t>Hello, world!</w:t>
</w:r>
</w:p>
</w:body>
</w:document>
The error message probably is a little misleading. HTML is simply invalid in this case.
Depending on whether or not you changed the HTML after creating it (with the Open XML PowerTools) from the original Word document, you will have to either transform it back into valid Open XML markup (if you changed it) or simply use the Open XML markup from the original Word document.

Tables width wrong when create file with google driveService

I am using c# and Google.Apis.Drive.V3 DriveService to create a document on google docs from HTML Razorview template. when I create the file to google docs the file is created successfully but with certain wrong format. I fixed almost all of this errors but there is one that is blowing my mind. I have tables that fit in entire document or HTML page, even when I specified the size of these tables in inches, cm or points anything works well. the tables have the wrong size when I upload the document and not cover 100% of the width. This is the picture that how the file is created:
Notice how even when I include a transparent pixel png on the first row, the table is smaller than I expected.
This is the code of the template that I am using for that:
<html>
<head>
<style type="text/css">
##import url('https://themes.googleusercontent.com/fonts/css?kit=fpjTOVmNbO4Lz34iLyptLSsvxyIpIjyXbTpruCFAaFx6IoWp0s0DOH-yFNIUq8XG');
##page {
size: 8.5in 11in;
margin: 1.5cm;
}
table, td, tr, th {
border: none;
}
.body-table {
border-spacing: 0;
border-collapse: collapse;
font-family: Lato, sans-serif;
border: none;
table-layout: fixed;
}
.v-align {
vertical-align: middle;
}
.h-center {
text-align: center;
}
.p {
padding-top: 0;
padding-bottom: 0;
line-height: 1.0;
orphans: 2;
widows: 2;
}
.prev-address {
color: #505759;
font-size: 9pt;
text-align: right;
width: 158.4pt;
}
.main-logo {
width: 158.4pt;
}
.prev-title {
font-size: 14pt;
text-align: center;
width: 230.4pt;
}
.width-30 {
width: 30%;
}
</style>
</head>
<body style="min-width: 21.59cm; padding: 1cm 1cm 1cm 1cm">
<table class="body-table" style="min-width: 19cm;">
<tbody>
<tr>
<td colspan="3"><img style="width: 19cm" src="mypixel.png"></td>
</tr>
<tr style="width: 19cm;">
<td class="main-logo width-30 v-align">Content 1</td>
<td class="prev-title width-30 v-align h-center">Content 2</td>
<td class="prev-address width-30">Content 3</td>
</tr>
</tbody>
</table>
</body>
</html>
And this is how I am uploading with google drive service in c#:
var fileContent = await
_viewRenderService.RenderToStringAsync("Quotes/PreviewTemplate", model);
var request = _driveService.Files.Create(new File
{
CreatedTime = DateTime.UtcNow,
MimeType = "application/vnd.google-apps.document",
Name = $"{fileName}.html"
}, fileContent.ToStream(), "text/html; charset=utf-8");
await request.UploadAsync();
Is there something that I am doing wrong to get this weird behavior?
UPDATE:
I realized that this issue is related to the padding of the page, notice how in the image the padding/margins were configured to 0.5 cm. So, it seems that Google uses some kind of max-width for the content in that page but only affect to the tables or maybe set a max-width for tables uploaded with drive API and align the content to the left of the document.

Insert HTML at CodeBehind, WebForm C#?

i have a method that generate tools based on the number value inserted, and I have another control called "DateTimePicker" that does the job of providing a textbox and the date+time picker function.
However, now the problem is that when i call dynamic_tools method and inserted the value "4" and "addInfoPanel" to the method.
The html code does not generating anything in the panel.
But, when i tried this html, it works.
lit.Text = #"<div class='errorMessage'>The user ID or password you entered does not match our records. Please try again. <br />
You may also securely recover your <a href='#'>User ID</a> or reset your <a href='#'>Password</a> online.
</div>";
I'm not too sure what is the reason behind this. I'm suspecting whether is it because of the custom control that i have created? any help is much appreciated. Thanks
Here's the code:
DateTimePicker.ascx.cs -> taken from https://github.com/jiestrada/DateTimePicker
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class DateTimePicker : System.Web.UI.UserControl
{
public string DateTime
{
get { return txtDateTime.Text; }
}
protected void Page_Load(object sender, EventArgs e)
{
DateTimePicker picker = this;
ScriptManager.RegisterClientScriptBlock(picker, picker.GetType(), "message", "<script type=\"text/javascript\" language=\"javascript\">getDateTimePicker();</script>", false);
}
}
DateTimePicker.ascx -> taken from https://github.com/jiestrada/DateTimePicker
<%# Control Language="C#" AutoEventWireup="true" CodeFile="DateTimePicker.ascx.cs"
Inherits="DateTimePicker" %>
<style type="text/css">
.textBox
{
width: 150px;
border-radius: 4px 4px 4px 4px;
color: #555555;
display: inline-block;
font-size: 14px;
height: 20px;
line-height: 20px;
margin-bottom: 10px;
padding: 4px 6px;
vertical-align: middle;
background-color: #FFFFFF;
border: 1px solid #CCCCCC;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
transition: border 0.2s linear 0s, box-shadow 0.2s linear 0s;
font-family: Helvetica Neue,Helvetica,Arial,sans-serif;
}
</style>
<script type="text/javascript" language="javascript">
function getDateTimePicker()
{
$('#datetimepicker').DateTimePickerNew({
format: 'dd/MM/yyyy hh:mm:ss',
language: 'en'
});
}
</script>
<div id="datetimepicker" class="input-append date">
<asp:TextBox ID="txtDateTime" CssClass="textBox" runat="server"></asp:TextBox>
<span class="add-on"><i data-time-icon="icon-time" data-date-icon="icon-calendar"></i>
</span>
</div>
<script type="text/javascript" language="javascript">
$('#datetimepicker').DateTimePickerNew({
format: 'dd/MM/yyyy hh:mm:ss',
language: 'en'
});
</script>
Dynamic Tools Method
protected string dynamic_tools(int key, PlaceHolder panel)
{
if (key == 4)
{
string value = "dtp"+i;
Literal lit = new Literal();
lit.Text = #"<td><DateTime:DateTimePicker ID='DateTimePicker' runat='server' /></td>";
panel.Controls.Add(lit);
}
}
HTML CODE
<%# Register Src="~/Control/DateTimePicker.ascx" TagName="DateTimePicker" TagPrefix="DateTime" %>
<div id="wrapper">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="singtelUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:PlaceHolder ID="addInfoPanel" runat="server" Visible="false"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
</div>
DateTimePicker dtp = new DateTimePicker();
dtp.ID = "someID";
//Add some attributes else, if you need. Such as a width, height, so on.
panel.Controls.Add(new LiteralControl("<td>"));
panel.Controls.Add(dtp);
panel.Controls.Add(new LiteralControl("</td>"));

How to show a div after postback on a button click?

Here i have a div in which i am showing it during the mouse hover in the master page and after mouse hover three href links will appear in that div .After clicking that href link it is traversing to another page,postback happens and that div is getting hidden in the master page.I need to show that div after that click also.I have used updatepanel and tried it but still it is not working.here is my code
//Div part
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="Update" runat="server">
<ContentTemplate>
<div runat="server" class="divSUBMenu" id="describe" style="width: 700px; height: 20px;
font: Arial, Helvetica, sans-serif;" onclick="show(0)">
</div>
</ContentTemplate>
</asp:UpdatePanel>
//Onhover part
<a href="#" onmouseover="showit(0)">
<img src="Images/Analyze_over.jpg" name="image1" width="84" height="22" border="0"
id="image1" alt="" /></a>
//Javascript for mousehover(working fine)
var submenu = new Array();
submenu[0] = ' <font style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;"><a style="color: #FFFFFF; text-decoration: none;" href="ATrendAnalysis.aspx">Trend Analysis</a> <a style="color: #FFFFFF; text-decoration: none;" href="AEventPerformance.aspx">Event Performance</a> <a style="color: #FFFFFF; text-decoration: none;" href="ACannibalization.aspx">Cannibalization</a> <a style="color: #FFFFFF; text-decoration: none;" href="AHaloEffect.aspx">Halo Effect</a> <a style="color: #FFFFFF; text-decoration: none;" href="AVolumeDecomposition.aspx">Volume Decomposition</a></font></span>';
var delay_hide = 500;
var menuobj = document.getElementById ? document.getElementById("describe") : document.all ? document.all.describe : document.layers ? document.dep1.document.dep2 : "";
function showit(which) {
clear_delayhide();
document.getElementById("describe").style.visibility = 'visible';
thecontent = (which == -1) ? "" : submenu[which];
if (document.getElementById || document.all) {
menuobj.innerHTML = thecontent;
}
else if (document.layers) {
menuobj.document.write(thecontent);
menuobj.document.close();
}
}
and finally the part below is not working during the onclick but this alert is working
function show(which) {
alert("test");
document.getElementById("describe").style.visibility = 'visible';
}
Any suggestion??
EDIT:
This is the href am clicking
<a style="color: #FFFFFF; text-decoration: none;" href="ATrendAnalysis.aspx">Trend Analysis</a>
You have to use ClientScriptManager
http://msdn.microsoft.com/en-us/library/3hc29e2a.aspx
Example:
void Page_Load(object sender, EventArgs e)
{
if(checkDisplayCount.Checked)
{
String scriptText = "";
scriptText += "function DisplayCharCount(){";
scriptText += " spanCounter.innerText = " +
" document.forms[0].TextBox1.value.length";
scriptText += "}";
ClientScriptManager.RegisterClientScriptBlock(this.GetType(),
"CounterScript", scriptText, true);
TextBox1.Attributes.Add("onkeyup", "DisplayCharCount()");
LiteralControl spanLiteral = new
LiteralControl("<span id=\"spanCounter\"></span>");
PlaceHolder1.Controls.Add(spanLiteral);
}
}
Since the div is set to runat=server, you could control this on the server side - setting describe.IsVisible = false initially, and changing it to describe.IsVisible = true post-click.
If for whatever reason this must be done on the client, due to reliance on other scripts or something, then make sure you're looking for the control by using the correct identifier - it could be, depending on the version of ASP.NET you're using, that the control is prefixed with ctl00_x. In fact, even in newer versions of ASP.NET (above .NET 3.5), I think the UpdatePanel might explicitly alter the identifiers of its elements using a prefix so as to keep track of what it contains, don't quote me on that though. Check the rendered markup output on the page to check this.

image in div via codebehind

I'm trying to achieve setting my image inside my div id =test this has became extremely problematic:
cn.Open();
using (OdbcCommand cmd = new OdbcCommand("SELECT Wallpostings FROM WallPosting WHERE UserID=" + userId + " ORDER BY idWallPosting DESC", cn))
{
using (OdbcDataReader reader = cmd.ExecuteReader())
{
var divHtml = new System.Text.StringBuilder();
while (reader.Read())
{
Image img = new Image();
img.ImageUrl = "~/userdata/2/uploadedimage/batman-for-facebook.jpg";
divHtml.Append("<div id=test>");
divHtml.Append(img + String.Format("{0}", reader.GetString(0)));
// how can I append an img inside my div id=test?
// the image must stay at the start of the div id=test + the contents(text) from my database (in that order)
divHtml.Append("</div>");
}
test1.InnerHtml = divHtml.ToString();
}
}
}
}
css:
* { padding: 0; margin: 0; outline: 0; }
body {
font-size: 12px;
line-height: 1.2;
font-family: Arial, "Trebuchet MS", sans-serif;
color: #a0a0a0;
background: url(images/bg.gif) repeat 0 0;
text-align: left;
}
div#test1 {
}
div#test
{
width:90%;
z-index:1;
padding:27.5px;
border-top: thin solid #736F6E;
border-bottom: thin solid #736F6E;
color:#ffffff;
margin:0 auto;
white-space: pre;
white-space: pre-wrap;
white-space: pre-line;
}
Asp html:
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<link href="css/style.css" rel="stylesheet" type="text/css" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="Server">
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.1.min.js" type="text/javascript"></script>
<p>
<asp:TextBox ID="TextBox1" name="TextBox1" runat="server" Rows="3"
Height="47px" Width="638px"></asp:TextBox>
</p>
<p>
<asp:Button ID="Button1" runat="server" Text="Post Message" Width="98px"
onclick="Button1_Click" />
</p>
<p>
</p>
<div id="test1" runat="server" />
// contents from my code go inside this div as div id=test
</asp:Content>
Firebug output:
<div id="ctl00_ContentPlaceHolder1_ContentPlaceHolder2_test1"><div id="test">System.Web.UI.WebControls.Imageweeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee</div><div id="test">System.Web.UI.WebControls.Imagehello</div><div id="test">System.Web.UI.WebControls.Imagestill trying</div><div id="test">System.Web.UI.WebControls.Imageback to front on comments</div><div id="test">System.Web.UI.WebControls.Imageback to front on comments</div><div id="test">System.Web.UI.WebControls.Imageback to front on comments</div><div id="test">System.Web.UI.WebControls.Imageback to front on comments</div><div id="test">System.Web.UI.WebControls.Imagelets try this again</div><div id="test">System.Web.UI.WebControls.Imagehair marry went up the hill</div><div id="test">System.Web.UI.WebControls.Imagewedfwedwe</div><div id="test">System.Web.UI.WebControls.Imagewedfwedwe</div><div id="test">System.Web.UI.WebControls.Imagekjgfkjh</div><div id="test">System.Web.UI.WebControls.Imageanother comment</div><div id="test">System.Web.UI.WebControls.Imagebla bla hope this works</div></div>
I know the reason why my code outputs the actual text of the web ui controls, I have had in another post code that actually gets the image up but it adds the image onto the "END" of the test div so rather than it look like this:
<div id="ctl00_ContentPlaceHolder1_ContentPlaceHolder2_test1">
<div id="test"><img src=blabla></img> the text goes after the image </div>
It looks like this:
<div id="ctl00_ContentPlaceHolder1_ContentPlaceHolder2_test1">
<div id="test"> text comes before image </div>
<img src=blabla></img>
<div id="test">hello</div>
<img src=blabla></img>
Which isn't what I want, the code I've added although I know the reasons why it outputs the web controls text is just a demonstration of "how" I'm trying to get it to work.
divTest.Append on img THEN text;
Of course I cant append I would have to use controls.add but I still couldn't get it to work.
Previous post is here so you can see some images and some ideas:
My code below gives me a problem, the image comes after the text
Image is a web control. You can't stick it in a StringBuilder.

Categories

Resources