Question
J'ai une application iOS qui prend un fichier html, le transforme en un fichier PDF, et les affiche sur une WebKit vue web. J'ai un problème bizarre où le fond d'une cellule de tableau est coupée quand je l'affiche au format PDF. La chose étrange est que le fond de la table est seulement interrompue lorsque le texte est centré. Si il est aligné à gauche, tout fonctionne bien. Pourquoi est-ce arrivé?
Veuillez noter que je ne suis pas à la recherche d'un travail autour de la solution. Je suis plutôt chercher à comprendre pourquoi cela se produit. Est-ce un bug dans iOS? Ou ai-je raté quelque chose?
Vue d'ensemble
Dans l'image ci-dessous, il y a deux tables de <table>
. Une table est grande, a une couleur rouge (corail) arrière-plan, et a une hauteur de 505px. L'autre table est en dessous de la première avec un fond blanc (la hauteur n'est pas défini). Les deux ont un peu de texte. Le texte est centré pour les deux tableaux.
La barre de navigation de titre affiche les détails de la vue actuelle. Par exemple, comme illustré dans l'image ci-dessous, un titre de PDF Paysage 505 signifie que le point de vue montre un PDF dans le paysage dimensions avec une hauteur de table de 505px.
Le Problème
Le problème se pose lorsque j'augmente la hauteur de 10px. Dans l'image ci-dessous, les principaux hauteur de la table est 515px et le bas de la table est désormais coupée.
Prendre exactement le même code html et css et changer uniquement le texte-alignement à être aligné à gauche. Maintenant le bas du tableau n'est pas coupé plus. J'ai aussi changé la couleur d'arrière-plan de vert de distinction. Vert signifie que le texte est aligné à gauche. Rouge signifie que le texte est centré.
L'image suivante montre une main-hauteur de la table de 745px et toujours le bas du tableau n'est pas coupé parce qu'il est aligné à gauche.
Code
Ci-dessous est le code html utilisé pour ce test.
<!DOCTYPE html>
<html>
<head>
<title>#COLOR#</title>
<meta charset="utf-8">
<style>
table, th, td {
border-collapse: collapse;
border: 3px solid black;
text-align: #ALIGN#;
}
table.main-table {
width: 1012px;
height: #HEIGHT#px;
background-color: #COLOR#;
}
table.bottom-table {
width: 1012px;
}
</style>
</head>
<body>
<table class="main-table">
<tr><td>Hello World.</td></tr>
</table>
<table class="bottom-table">
<tr><td>This text gets cut off when centered. It does *not* get cut when left-aligned.</td></tr>
</table>
</body>
</html>
En MyViewController
, l' getHTML()
fonction tire le code source html d' sample.html
. La fonction remplace alors #ALIGN#
, #COLOR#
, et #HEIGHT#
avec leurs valeurs respectives.
func getHTML() -> String? {
let htmlPath: String? = Bundle.main.path(forResource: htmlResource, ofType: "html")
guard let path = htmlPath else { return nil }
do {
// Load the HTML template code into a String variable.
var html = try String(contentsOfFile: path)
html = html.replacingOccurrences(of: "#HEIGHT#", with: tableHeight.description)
html = html.replacingOccurrences(of: "#COLOR#", with: colorState.rawValue)
html = html.replacingOccurrences(of: "#ALIGN#", with: alignState.rawValue)
return html
} catch {
print("Error: " + error.localizedDescription)
}
return nil
}
Le PDFBuilder classe gère la création de PDF avec une fonction:
static func exportHTMLToPDF(html: String, frame: CGRect) -> Data {
// Set a printable frame and inset
let pageFrame = frame
let insetRect = pageFrame.insetBy(dx: 10.0, dy: 10.0)
// Create a UIPrintPageRenderer and set the paperRect and printableRect using above values.
let pageRenderer = UIPrintPageRenderer()
pageRenderer.setValue(pageFrame, forKey: "paperRect")
pageRenderer.setValue(insetRect, forKey: "printableRect")
// Create a printFormatter and pass the HTML code as a string.
let printFormatter = UIMarkupTextPrintFormatter(markupText: html)
// Add the printFormatter to the pageRenderer
pageRenderer.addPrintFormatter(printFormatter, startingAtPageAt: 0)
// This data var is where the PDF will be stored once created.
let data = NSMutableData()
// This is where the PDF gets drawn.
UIGraphicsBeginPDFContextToData(data, pageFrame, nil)
UIGraphicsBeginPDFPage()
pageRenderer.drawPage(at: 0, in: UIGraphicsGetPDFContextBounds())
print("bounds: " + UIGraphicsGetPDFContextBounds().debugDescription)
UIGraphicsEndPDFContext()
return data as Data
}
Ce projet est sur Github: https://github.com/starkindustries/PrintPDFTest
Étapes De Dépannage Prises
- Dimensions: j'ai essayé de jouer avec la taille du fichier PDF dimensions. Ce n'est pas faire une différence dans le résultat.
- Colonnes: j'ai essayé d'utiliser plusieurs colonnes au lieu d'une seule. Même problème; pas de différence.
- Tables: j'ai essayé d'utiliser une seule table au lieu de deux. Avec une table et deux cellules, la cellule du bas encore coupée lorsque le texte est centré; en bas de la cellule ne pas se couper lorsque le texte est aligné à gauche.
- iphone: j'ai essayé de simuler sur différents appareils iPhone (iPhone 6s, iPhone 8, l'iPad Pro). Même problème.
- Div: Si vous utilisez un div au lieu d'un second tableau, le problème est magiquement fixe. Mais pourquoi un div de travail et non pas un tableau?
Note L'App
La barre d'outils supérieure a deux boutons: vert et rouge. Le vert rend le texte aligné à gauche. Rouge rend le texte centré.
La barre d'outils en bas dispose de cinq boutons: rembobinage, html, portrait, paysage, et avance rapide. Le rewind bouton réduit la table principale de la hauteur par 10px. Avance rapide augmente la hauteur de 10px. Le code html du bouton indique l'affichage html. Portrait et paysage afficher les fichiers PDF dans leurs orientations respectives.