web-dev-qa-db-fra.com

Écrire un fichier HTML en utilisant Java

Je veux que mon application Java écrive du code HTML dans un fichier. En ce moment, je code durement les balises HTML en utilisant la classe Java.io.BufferedWriter. Par exemple:

BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.write("<html><head><title>New Page</title></head><body><p>This is Body</p></body></html>");
bw.close();

Y a-t-il un moyen plus facile de faire cela, car je dois créer des tables et cela devient très gênant?

39

Si vous voulez le faire vous-même, sans utiliser de bibliothèque externe, une méthode simple consisterait à créer un fichier template.html avec tout le contenu statique, comme par exemple:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>$title</title>
</head>
<body>$body
</body>
</html>

Placez une balise telle que $tag pour tout contenu dynamique, puis procédez comme suit:

File htmlTemplateFile = new File("path/template.html");
String htmlString = FileUtils.readFileToString(htmlTemplateFile);
String title = "New Page";
String body = "This is Body";
htmlString = htmlString.replace("$title", title);
htmlString = htmlString.replace("$body", body);
File newHtmlFile = new File("path/new.html");
FileUtils.writeStringToFile(newHtmlFile, htmlString);

Remarque: j'ai utilisé org.Apache.commons.io.FileUtils pour des raisons de simplicité.

39
Marco Lackovic

Il y a quelques mois, j'ai eu le même problème et chaque bibliothèque que j'ai trouvée fournit trop de fonctionnalités et de complexité pour mon objectif final. Je finis donc par développer ma propre bibliothèque - HtmlFlow - qui fournit une API très simple et intuitive qui me permet d’écrire HTML dans un style fluide. Vérifiez-le ici: https://github.com/fmcarvalho/HtmlFlow (il supporte également dynamic binding to HTML elements)

Voici un exemple de liaison des propriétés d'un objet Task dans des éléments HTML. Considérons une classe Java Task avec trois propriétés: Title, Description et une Priority et nous pouvons ensuite produire un document HTML pour un objet Task de la manière suivante:

import htmlflow.HtmlView;

import model.Priority;
import model.Task;

import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.PrintStream;

public class App {

    private static HtmlView<Task> taskDetailsView(){
        HtmlView<Task> taskView = new HtmlView<>();
        taskView
                .head()
                .title("Task Details")
                .linkCss("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css");
        taskView
                .body().classAttr("container")
                .heading(1, "Task Details")
                .hr()
                .div()
                .text("Title: ").text(Task::getTitle)
                .br()
                .text("Description: ").text(Task::getDescription)
                .br()
                .text("Priority: ").text(Task::getPriority);
        return taskView;
    }

    public static void main(String [] args) throws IOException{
        HtmlView<Task> taskView = taskDetailsView();
        Task task =  new Task("Special dinner", "Have dinner with someone!", Priority.Normal);

        try(PrintStream out = new PrintStream(new FileOutputStream("Task.html"))){
            taskView.setPrintStream(out).write(task);
            Desktop.getDesktop().browse(URI.create("Task.html"));
        }
    }
}
11
Miguel Gamboa

Velocity est un bon candidat pour écrire ce genre de choses.
Il vous permet de garder votre code HTML et code de génération de données aussi séparés que possible.

5
PATRY Guillaume

Vous pouvez utiliser jsoup ou wffweb (HTML5).

Exemple de code pour jsoup: -

Document doc = Jsoup.parse("<html></html>");
doc.body().addClass("body-styles-cls");
doc.body().appendElement("div");
System.out.println(doc.toString());

empreintes

<html>
 <head></head>
 <body class=" body-styles-cls">
  <div></div>
 </body>
</html>

Exemple de code pour wffweb: -

Html html = new Html(null) {{
    new Head(this);
    new Body(this,
        new ClassAttribute("body-styles-cls"));
}};

Body body = TagRepository.findOneTagAssignableToTag(Body.class, html);
body.appendChild(new Div(null));

System.out.println(html.toHtmlString());
//directly writes to file
html.toOutputStream(new FileOutputStream("/home/user/filepath/filename.html"), "UTF-8");

tirages (au format minifié): -

<html>
<head></head>
<body class="body-styles-cls">
    <div></div>
</body>
</html>
5
RRadley

Je vous recommande vivement d'utiliser un langage de template très simple, tel que Freemarker

5
npellow

Cela dépend vraiment du type de fichier HTML que vous créez.

Pour de telles tâches, j’utilise pour créer un objet, le sérialiser en XML, puis le transformer avec XSL. Les avantages de cette approche sont:

  • La séparation stricte entre le code source et le modèle HTML,
  • La possibilité d'éditer du HTML sans avoir à recompiler l'application,
  • La possibilité de servir différents HTML dans différents cas basés sur le même XML, ou même de servir XML directement en cas de besoin (pour une désérialisation plus poussée par exemple),
  • La quantité de code plus courte à écrire.

Les inconvénients sont:

  • Vous devez connaître XSLT et savoir l'implémenter en Java.
  • Vous devez écrire XSLT (et c'est une torture pour beaucoup de développeurs).
  • Lors de la transformation de XML en HTML avec XSLT, certaines parties peuvent être délicates. Quelques exemples: balises <textarea/> (qui rendent la page inutilisable), déclaration XML (pouvant poser des problèmes avec IE), espace (avec les balises <pre></pre>, etc.), entités HTML (&nbsp;), etc.
  • Les performances seront réduites, car la sérialisation au format XML gaspille beaucoup de ressources de processeur et la transformation XSL est également très coûteuse.

Maintenant, si votre HTML est très court ou très répétitif ou si le HTML a une structure volatile qui change de façon dynamique, cette approche ne doit pas être prise en compte. D'autre part, si vous servez des fichiers HTML ayant une structure similaire et que vous souhaitez réduire la quantité de code Java et utiliser des modèles, cette approche peut fonctionner.

3

Si vous voulez utiliser Groovy, MarkupBuilder est très pratique pour ce genre de choses, mais je ne sais pas si Java a quelque chose de semblable. 

http://groovy.codehaus.org/Creating+XML+using+Groovy 's + MarkupBuilder

1
Eric Wilson

si cela devient un travail répétitif; Je pense que vous shud faire la réutilisation de code! pourquoi ne pas simplement écrire des fonctions qui "écrivent" de petits blocs de construction de HTML. avoir l'idée? voir eg. vous pouvez avoir une fonction à laquelle vous pouvez passer une chaîne et le placer automatiquement dans une balise de paragraphe et la présenter. Bien sûr, vous auriez également besoin d’écrire une sorte d’analyseur de base pour le faire (comment la fonction saurait-elle où joindre le paragraphe!) Je ne pense pas que vous soyez un débutant .. donc je ne suis pas en train d'élaborer ... dites-moi si vous ne comprenez pas ..

0
Chani

Les modèles et autres méthodes basés sur la création préliminaire du document en mémoire sont susceptibles d'imposer certaines limites à la taille du document résultant.

Entre-temps, il existe une approche très simple et fiable pour la création au format HTML simple, basée sur un gestionnaire SAX et un transformateur XSLT par défaut, ce dernier ayant la capacité intrinsèque de sortie HTML:

String encoding = "UTF-8";
FileOutputStream fos = new FileOutputStream("myfile.html");
OutputStreamWriter writer = new OutputStreamWriter(fos, encoding);
StreamResult streamResult = new StreamResult(writer);

SAXTransformerFactory saxFactory =
    (SAXTransformerFactory) TransformerFactory.newInstance();
TransformerHandler tHandler = saxFactory.newTransformerHandler();
tHandler.setResult(streamResult);

Transformer transformer = tHandler.getTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "html");
transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
transformer.setOutputProperty(OutputKeys.INDENT, "yes");

writer.write("<!DOCTYPE html>\n");
writer.flush();
tHandler.startDocument();
    tHandler.startElement("", "", "html", new AttributesImpl());
        tHandler.startElement("", "", "head", new AttributesImpl());
            tHandler.startElement("", "", "title", new AttributesImpl());
                tHandler.characters("Hello".toCharArray(), 0, 5);
            tHandler.endElement("", "", "title");
        tHandler.endElement("", "", "head");
        tHandler.startElement("", "", "body", new AttributesImpl());
            tHandler.startElement("", "", "p", new AttributesImpl());
                tHandler.characters("5 > 3".toCharArray(), 0, 5); // note '>' character
            tHandler.endElement("", "", "p");
        tHandler.endElement("", "", "body");
    tHandler.endElement("", "", "html");
tHandler.endDocument();
writer.close();

Notez que le transformateur XSLT vous évitera d’échapper aux caractères spéciaux tels que >, car il en prend soin lui-même.

Et il est facile d’envelopper les méthodes SAX telles que startElement() et characters() dans un format plus pratique à votre goût ...

0
Sergey Ushakov

J'avais aussi des difficultés à trouver quelque chose de simple pour satisfaire mes besoins, alors j'ai décidé d'écrire ma propre bibliothèque (avec la licence MIT). Il est principalement basé sur des motifs composites et constructeurs. 

Un exemple déclaratif de base est:

import static com.github.manliogit.javatags.lang.HtmlHelper.*;

html5(attr("lang -> en"),
  head(
    meta(attr("http-equiv -> Content-Type", "content -> text/html; charset=UTF-8")),
    title("title"),
    link(attr("href -> xxx.css", "rel -> stylesheet"))
  )
).render();

Un exemple courant est:

ul()
  .add(li("item 1"))
  .add(li("item 2"))
  .add(li("item 3"))     

Vous pouvez vérifier plus d'exemples ici

J'ai également créé un convertisseur en ligne pour transformer tous extrait de code HTML (du modèle d'amorçage complexe au extrait de code simple) à la volée (c'est-à-dire html -> javatags)

0
M. Modugno