20251118 EjercicioJSON_PDF_1 - Contenido educativo
Ajuste de pantallaEl ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:
Vale, pues entonces
00:00:00
Yo directamente
00:00:03
Copié y pegué esta aplicación
00:00:04
La copié y la pegué
00:00:07
Hice un copy y pega
00:00:09
A partir de ella, es lo más cómodo, ¿no?
00:00:10
Porque es una arquitectura similar a la que vamos a usar
00:00:12
Pues hice un copy y pega de la aplicación
00:00:14
La cambié de nombre
00:00:16
Y llegué a esta aplicación
00:00:17
¿Vale?
00:00:19
Entonces, lo que tenía que hacer
00:00:22
Esta aplicación es
00:00:26
Dado un fichero xml
00:00:27
que le vamos a dar a la aplicación
00:00:30
que el fichero
00:00:33
pues
00:00:34
era
00:00:36
este de aquí
00:00:38
este de la
00:00:40
fórmula 1
00:00:42
este fichero JSON
00:00:43
vamos a hacer un listado
00:00:46
PDF con datos que vamos a extraer
00:00:48
de aquí, entonces como es JSON
00:00:51
pues automáticamente lo vamos a tener que leer
00:00:52
con alguna librería que lo sepa parsear
00:00:54
en nuestro caso Jackson
00:00:56
no es la que hemos mencionado, porque es la
00:00:58
más completa y la más usada
00:01:00
y de aquí vamos a sacar
00:01:02
pues una serie de cosas, entonces primero
00:01:04
tengo que tener el chip de, ah vale
00:01:06
vas a usar Jackson
00:01:08
muy bien, para leer esto, entonces uno lo recuerda
00:01:10
ya lo tiene situado en la cabeza
00:01:13
para poder pillar de él, en el momento
00:01:14
en el que ya lo necesite, bueno pues entonces
00:01:16
esta aplicación, según el copia
00:01:18
y pega, tenía su
00:01:20
su, uy
00:01:22
bueno, ahí coño
00:01:27
se me va
00:01:32
Que mal veo, vale
00:01:32
Lo primero que hacía esta aplicación
00:01:34
Era arrancarte el index
00:01:37
Eso no lo tenemos que tocar
00:01:38
Nosotros subimos nuestro
00:01:41
Fichero desde nuestro index
00:01:42
Sube aquí tu archivo JSON y ya está
00:01:45
El index lo tocamos
00:01:46
Vale, entonces
00:01:47
Eso es lo que
00:01:49
Recogía el controlador
00:01:52
Que lo tengo aquí
00:01:55
El controlador en la ruta inicial
00:01:58
te descargaba el index
00:02:01
pues el controlador
00:02:03
esto no lo tengo ni que tocar
00:02:04
te muestra mi index y es que mi index
00:02:07
me vale, tal cual, subir el archivo
00:02:09
pues hasta aquí la aplicación es que sigue
00:02:12
siendo la misma
00:02:13
vale, que es lo que ocurre
00:02:14
luego después cuando yo le doy a subir
00:02:18
pues cuando yo le doy a subir el archivo
00:02:19
el upload, el controlador ya va
00:02:22
aquí, upload
00:02:24
este método, entonces la primera
00:02:27
parte tampoco cambia, la primera
00:02:29
parte es la que del parámetro este file que guardo en un parámetro multipart file, pues este parámetro
00:02:31
saco los bytes y me creo un archivo local en la ruta que yo quiera de mi equipo, pues en este caso
00:02:40
yo he puesto en esta, esta es la ruta local del servidor donde guarda los archivos con los que
00:02:46
trabaja, pues me creo
00:02:52
este archivo local
00:02:54
con el nombre
00:02:56
del parámetro subido
00:02:57
y ahora ya tengo el archivo
00:03:00
ahí, lo tengo aquí
00:03:02
ahí subido
00:03:03
aquí
00:03:06
en esta variable
00:03:08
y ahora, esto es lo único que cambia
00:03:09
lo único que cambia es
00:03:12
que en lugar de llamar a
00:03:14
conviérteme de JSON
00:03:16
perdón, de XML a JSON
00:03:17
generame el informe
00:03:19
Entonces, esta línea que en nuestra otra aplicación era esta, era esta, pues en lugar de llamar a este método, me tengo que hacer ahora ya sí el que me interesa, me tengo que hacer el que me interesa, ¿vale?
00:03:21
Bueno, pues entonces, para eso me he creado este método estático dentro de la clase lógica, que ahora la abrimos, y este método estático yo le paso el fichero que ya está guardado localmente, porque lo acabo de subir, que está aquí, lo paso en file, y este método, lo que yo quiero que haga, siempre antes de empezar a programar algo, uno tiene que hacer un análisis previo, lógicamente,
00:03:43
Entonces, una aplicación inicialmente tiene que ser un conjunto de firmas, con firmas me refiero a cabeceras de métodos, entonces eso casi es lo más difícil de una aplicación, el hacer todas las cabeceras de métodos, todas las firmas que van a reproducir lo que tú quieres que pase.
00:04:11
luego ya ir rellenando cada método por dentro
00:04:27
ya son detalles
00:04:29
bueno, pues yo aquí, ¿qué necesito?
00:04:30
yo aquí necesito un pdf
00:04:33
¿vale? pues voy a necesitar un método
00:04:35
al que le paso mi fichero local
00:04:37
que acabo de guardar
00:04:39
y le voy a dar
00:04:41
el nombre del pdf
00:04:43
donde lo va a guardar, pues enlistado
00:04:45
pdf, por ejemplo, este mismo
00:04:47
lo primero que puse
00:04:49
en la misma ruta
00:04:50
donde estoy trabajando
00:04:52
entonces el resultado final
00:04:54
de este método tiene que ser que mi archivo
00:04:57
file genere un pdf
00:04:59
que guarde ahí
00:05:01
¿vale? y luego ya
00:05:02
el resto de este método del controlador no cambia
00:05:04
me va a devolver una página
00:05:07
de descarga, una página de descarga
00:05:09
con un parámetro oculto
00:05:11
que voy a llamar así
00:05:13
lógicamente porque es el mismo nombre que he puesto aquí
00:05:15
un parámetro oculto
00:05:17
y ahora ya
00:05:18
la página de descarga
00:05:19
va a invocar a download
00:05:23
y esto no cambia
00:05:25
esto es exactamente el mismo que tenía
00:05:26
en la otra aplicación, no ha cambiado
00:05:29
lo que voy a descargar aquí es
00:05:30
pues el fichero que se llame
00:05:33
como el parámetro oculto que he pasado aquí
00:05:35
o sea, lo único que cambia ahora mismo, con la copia que yo he hecho
00:05:36
el copia y pega de las dos aplicaciones
00:05:39
lo único que ha cambiado
00:05:41
de todo el controlador
00:05:43
es esta línea, es lo único que ha cambiado
00:05:45
de todo el controlador, ¿vale?
00:05:47
el contenido web
00:05:50
es el mismo, el index es el mismo
00:05:51
la página de descarga será
00:05:53
la misma, todo es lo mismo
00:05:55
ahora me tengo que centrar
00:05:57
en esta parte
00:05:59
bueno, pues entonces me hago
00:06:00
la clase lógica
00:06:03
y ahí el método
00:06:04
entonces la clase
00:06:06
lógica es esta y aquí ya está
00:06:08
el método
00:06:11
vale, pues esto
00:06:11
del JSON file me genera
00:06:14
un PDF con este nombre, pues aquí
00:06:17
ya es hacer
00:06:19
lo que ya sabemos. Primero, la parte de generar el informe
00:06:20
va a necesitar una lista con los datos que yo quiero recoger
00:06:26
en el informe. Entonces, antes de nada, vamos a pensar
00:06:32
a ver qué datos necesito yo en el informe, qué datos necesito.
00:06:36
Pues los voy a meter en una clase aparte, aquí en este paquete
00:06:41
de informe, los voy a meter aquí, que son el equipo, el corredor
00:06:46
y los puntos. Estos son los datos. Pues esta es la clase que recoge
00:06:49
los tres datos que van al informe. Luego
00:06:54
este método de aquí, este método necesita
00:06:58
una lista con esos datos.
00:07:02
Bueno, pues entonces tengo yo que irlos construyendo
00:07:07
a partir de todos y cada uno de los corredores
00:07:10
del JSON. Bueno, pues vamos a leer el JSON con
00:07:14
la librería Jackson exactamente
00:07:18
igual que hicimos en el ejemplo de Jackson
00:07:21
igual, es que no tenemos que cambiar nada
00:07:23
vale, pues ¿qué hicimos en la librería
00:07:24
de Jackson? pues convertimos
00:07:27
el JSON a un objeto
00:07:28
con la estructura de clases que hay
00:07:30
aquí, que es la forma más fácil de trabajar
00:07:33
pero yo puedo leer el JSON no de empezar
00:07:34
a leer dentro de los JSON
00:07:37
no de que hay debajo y navegar
00:07:38
y no necesito ningún modelo
00:07:40
pero si tengo
00:07:42
la opción de hacerme un modelo de clases
00:07:45
que representan ese JSON es mucho más fácil
00:07:46
porque convierto el JSON
00:07:48
en un objeto raíz
00:07:50
y ya está, y a partir de ahí ya programo
00:07:52
de toda la vida, entonces si tengo esa opción es lo más fácil
00:07:54
¿vale? pero claro, tengo que poder
00:07:56
crearme yo unas clases modelo y tenerlas
00:07:58
ahí y que nadie me diga, oye, esto molesta mucho
00:08:00
bueno, pues como
00:08:03
aquí no me han dicho que no haga eso
00:08:04
pues venga, vamos a
00:08:06
hacer unas clases modelo que
00:08:08
representen esto
00:08:10
esto
00:08:11
son directamente objetos, entonces esto es muy fácil de hacer
00:08:12
pues tengo mi objeto raíz, mi objeto raíz que tendrá
00:08:19
una variable string y una lista de corredores, luego otra clase corredor
00:08:22
cada clase corredor tendrá estas propiedades y a su vez
00:08:26
un único objeto estadísticas, luego una tercera clase
00:08:31
y esta tercera clase ya tiene estas cuatro, luego tres clases
00:08:34
la raíz corredor de la cual la raíz tiene una lista
00:08:37
y estadísticas de las cuales cada corredor tiene un único objeto.
00:08:41
Pues venga, me hago esas tres clases
00:08:46
y las meto aquí en el modelo.
00:08:49
Vale, fórmula 1.
00:08:54
Vale, bueno, esto lo hice así por comodidad.
00:08:56
Luego os explico lo que es esto, ¿vale?
00:08:59
Porque es una forma rápida de ahorrarte lo de los getter y los setter
00:09:02
y cómoda
00:09:07
lo que pasa es que está solo desde no sé qué versión
00:09:11
15, 16, 17, no lo sé cuál
00:09:13
17, puede ser, sí
00:09:14
en realidad
00:09:17
es lo que sustituye al antiguo
00:09:19
bueno, antiguo que se sigue usando
00:09:21
¿suena a Lombok?
00:09:23
¿de qué te suena a Lombok?
00:09:25
bueno, luego lo mencionamos
00:09:29
también
00:09:30
Lombok es una manera
00:09:30
es una pequeña librería
00:09:33
para que te genere automáticamente los Better y Setter
00:09:34
Ahora mismo lo olvidamos. Vale, pues ahora mismo, olvidaos del récord este, lo puse a propósito para acordarme de explicarlo, pero esta es la clase Fórmula 1 con sus dos propiedades, temporada y corredores, ¿vale? Temporada y corredores.
00:09:37
Deberían tener aquí los getter y setter
00:09:57
Pero el récord me lo ahorra
00:10:00
Porque, batatín, luego lo explicamos
00:10:02
Porque me lo ahorra, ¿vale?
00:10:04
Ahora, necesito corredor
00:10:06
Corredor, pues corredor
00:10:07
Tiene
00:10:10
Esto lo he hecho con Lombok, también para
00:10:11
Ahorrármelo y para
00:10:14
Aprovechar y explicarlo, corredor tiene
00:10:15
Estas, y de nombre
00:10:18
Equipo, país, número y estadísticas
00:10:20
Aquí es como si tuviera los getter y setter
00:10:22
Imaginad que los tiene
00:10:24
¿Vale? No los tiene gracias a esta anotación
00:10:26
Que yo le he puesto aquí
00:10:28
Pero es como si los tuviera
00:10:29
¿Vale? Olvidados por ahora de eso
00:10:31
Y ahora estadísticas tiene
00:10:33
Estadísticas tiene esto
00:10:35
Y ya está
00:10:39
Luego el modelo ya lo tengo hecho con esas tres
00:10:40
Claro, el modelo podría
00:10:44
Se lo puedo pedir a HGPT
00:10:46
Y lógicamente le digo
00:10:48
Dame el modelo de clases de este JSON
00:10:49
Y me lo va a hacer, pero es que esto en particular
00:10:51
Es que es muy rápido
00:10:54
Casi es más fácil que lo haga uno
00:10:55
Porque se asegura de que no comete ningún error
00:10:58
O no lo interpreta mal
00:11:00
Bueno, pues ahora que ya tenemos el modelo
00:11:01
Ahora ya de leer del JSON
00:11:03
En el método este de lógica
00:11:05
Ya es copiar y pegarlo
00:11:07
Que ya sabemos hacer
00:11:09
El mapper que me va a hacer todo
00:11:09
En el mapper me leo el nodo raíz
00:11:13
Y luego ya que hago con mi nodo raíz
00:11:17
Pues podría navegar por él
00:11:21
Y hacer con eso datos informes
00:11:23
Repito, pero más fácil
00:11:26
Como tengo las clases del modelo
00:11:28
Lo convierto
00:11:29
A un objeto
00:11:31
Fórmula y ya está
00:11:33
Y a partir de ahí a Jackson no me hace
00:11:35
Falta para nada, tengo mi objeto
00:11:37
Fórmula y ya está
00:11:39
De hecho lo he dado en dos pasos
00:11:40
Y ni siquiera
00:11:43
Porque el propio mapper tiene ya un método
00:11:44
Para del fichero
00:11:47
Mandártelo a un objeto, pero bueno
00:11:48
Como estos son los dos que mencionamos
00:11:50
Es decir, Jackson tiene millones de posibilidades de métodos de cosas, pero bueno, de cara al examen vamos a centrarnos en las tres, cuatro cosas que hemos visto. Bueno, pues lo que vimos es leer un nodo raíz, navegar por él, en el ejemplo vimos cómo podemos navegar por él con el find value o convertirlo a un objeto.
00:11:52
si yo tengo el modelo
00:12:16
aquí lo convierto al objeto que tengo el modelo
00:12:17
y ya está, y ahora se trata de hacer esto
00:12:19
se trata de hacer esto
00:12:22
y para hacer esto tendré que ir corredor por corredor
00:12:24
haciendo esto
00:12:26
¿vale?
00:12:28
entonces aquí lo tengo comentado porque lo
00:12:31
hice de las dos
00:12:34
formas para, vale
00:12:36
entonces ya está, si me olvido de los
00:12:38
streams y lo hago a mano
00:12:40
como toda la vida
00:12:42
pues ya está, voy corredor por corredor
00:12:43
Para cada corredor
00:12:45
Me creo un objeto de estos
00:12:48
Y lo añado
00:12:49
A mi lista de datos informe
00:12:52
Y ya está
00:12:53
Y ahora ya, copia y pega del Jasper Report
00:12:54
Y se acabó, ya he terminado la aplicación
00:12:57
Se acabó, no tengo más que hacer
00:13:00
Luego lo único que tengo que hacer es copiar y pegar un proyecto
00:13:01
Y completar este método
00:13:04
¿Vale?
00:13:06
Entonces
00:13:08
Esto de aquí está
00:13:08
Para hacer esto mismo
00:13:10
Con streams
00:13:12
¿Vale?
00:13:13
Porque aquí en realidad, ¿qué hemos hecho?
00:13:15
Para cada corredor de mi lista hago algo.
00:13:20
¿El qué? Crear un objeto de datos informe.
00:13:25
Es decir, lo puedo ver como que cada corredor de mi lista
00:13:28
lo estoy convirtiendo en objeto de datos informe.
00:13:32
Entonces, si yo mi fila de corredores la convirtiera en una fila de datos informe,
00:13:36
pues luego esa fila la paso a lista y se acabó.
00:13:42
Entonces, pues hombre, convertir una fila de cosas a otra fila de cosas es precisamente el map
00:13:44
Es justo el map
00:13:50
Pues hombre, entonces me voy a hacer una filita con mis corredores
00:13:51
Voy a hacer una filita con mis corredores
00:13:57
Y ahora cada corredor lo voy a transformar a un objeto datos informe
00:14:00
¿Qué es lo que cambia aquí respecto a lo que estamos acostumbrados?
00:14:06
que normalmente nuestros métodos
00:14:10
de string, los que usamos
00:14:12
no tienen
00:14:14
varias líneas en la segunda parte
00:14:16
o sea, cada corredor transforma algo a no sé qué
00:14:18
entonces nos ahorramos el retun
00:14:20
porque va implícito, pero en realidad
00:14:22
el map es, para cada objeto
00:14:24
corredor, me devuelve
00:14:26
retun lo que sea, pero porque
00:14:28
solo hay una línea que es ya el valor que devuelve
00:14:30
pero en este caso no es tan fácil
00:14:32
para cada corredor hay que hacer muchas
00:14:34
cosas, no pasa nada
00:14:36
lo metemos entre llaves
00:14:38
¿vale? para cada corredor
00:14:39
crea un objeto de datos informe
00:14:42
rellénalo con las propiedades
00:14:44
y este es el que me devuelve
00:14:46
aquí sí que hay que poner un return
00:14:48
porque hay varias líneas
00:14:49
¿vale? esto pues lo
00:14:51
mencionamos en su momento de cuando la
00:14:53
parte
00:14:56
la segunda parte de la lambda son varias
00:14:57
líneas, ya es un código que pueden ser
00:15:00
todas las que haya, todas las que quieran
00:15:01
hay que ponerlas ya entre llaves, eso sí
00:15:03
y si es un map porque te devuelve
00:15:05
algo, pues un return
00:15:08
bueno pues entonces
00:15:09
ya hemos convertido nuestra filita
00:15:13
de corredores, la acabamos
00:15:15
de convertir en una filita de datos
00:15:18
informe, ahora esa filita la llevamos a lista
00:15:20
y ya está
00:15:22
ya tenemos esta lista de una manera un poco más
00:15:23
bonita
00:15:26
que este for each de aquí
00:15:27
pero no te gusta más esto
00:15:29
y además el manejo
00:15:33
interno de todo esto, estoy convencida
00:15:39
no lo sé
00:15:41
el for each
00:15:41
tiene unas implicaciones
00:15:43
de bloqueo
00:15:46
que seguramente
00:15:49
estén resueltas aquí ya, no lo sé
00:15:50
bueno
00:15:53
no os gusta, vale
00:15:56
pero acostumbrad, es cómodo
00:15:58
es que verdaderamente es muy cómodo
00:16:01
tienes una lista y quieres hacer cosas con ella
00:16:02
pues en lugar de plantearte el algoritmo
00:16:04
de la recorro o no sé qué
00:16:07
a esa lista la pones en fila
00:16:08
es decir, pones stream, pones el punto
00:16:11
y ahí se te abre el universo
00:16:13
entero de posibilidades, pues explora
00:16:15
a ver si alguna te interesa, y casi seguro
00:16:17
que alguna te interesa
00:16:18
entonces, es cambiar el chip
00:16:19
tengo que hacer cosas con una lista
00:16:22
la serializo con stream
00:16:24
y ahora veo que me ofreces
00:16:26
pues casi seguro que pum
00:16:28
lo que me ofreces
00:16:30
se encaja justo en lo que yo quiero hacer
00:16:33
claro, luego hay que manejar
00:16:34
un poquito la construcción básica
00:16:36
de landas, porque son
00:16:38
los parámetros para
00:16:40
esos métodos de stream son landas
00:16:41
entonces
00:16:44
hay que manejarlo
00:16:45
no, simplemente le cambió la sender
00:16:47
y por qué, porque lleva mucho sin tocarlo
00:16:49
no, porque no es mejor que pulsar
00:16:52
vale, pues ya tenemos
00:16:54
la lista de datos informe
00:17:00
y ahora ya hacemos el copia y pega del Jasper Report
00:17:02
me creo
00:17:04
mi fuente de datos
00:17:06
el Jasper Report
00:17:08
asocia
00:17:09
La plantilla, claro nos falta hacer la plantilla
00:17:10
Hacemos básica la plantilla
00:17:14
Me tengo que ir al Jaspers of Studio a hacerla
00:17:15
Y esa plantilla
00:17:17
La puedo hacer rápido si la hago mínima
00:17:19
De tal forma que solamente tenga
00:17:21
Estas tres fills
00:17:23
Estos tres, se acabó, no me complico más la vida
00:17:25
Vale
00:17:28
¿Hacerla aquí te refieres a hacer
00:17:30
El jrxml?
00:17:37
Bueno, yo la plantilla la tengo
00:17:42
Aquí, lógicamente, mi plantilla es esta
00:17:44
Que la he metido
00:17:47
En
00:17:48
Donde la tengo, jolines
00:17:49
Sí, pero no veo la carpeta
00:17:51
Aquí abajo, vale
00:17:53
Vale, pero esa plantilla la he tenido que hacer
00:17:55
Con
00:17:58
El Jasper Software Studio
00:17:59
¿Que vas a escribir el jrxml aquí directamente?
00:18:00
Es que no te entiendo, no sé a qué quieres decir
00:18:03
Pero, ¿cómo?
00:18:04
Pero
00:18:29
Es que no sé lo que quieres decir
00:18:29
O sea, lo que me está
00:18:32
Con otra herramienta, de otra manera
00:18:33
Sin el Jasper Report
00:18:35
vale, entonces, ¿cómo has construido
00:18:36
el PDF? es que yo no lo sé
00:18:41
o sea, que esto has hecho lo desconozco
00:18:42
pero bueno, vamos a completar esto y luego
00:18:44
nos lo enseñas, ¿vale?
00:18:46
vale, entonces
00:18:48
tengo yo aquí mis datos informe
00:18:49
hago el copia y pega, ¿dónde estamos?
00:18:52
ah, estábamos
00:18:59
aquí, vale
00:19:00
hago mi copia y pega
00:19:01
de aquí
00:19:04
del Jasper Report
00:19:05
le digo, esta es la plantilla que tienes
00:19:07
que rellenar con datos informe la relleno a goles por manager y ya está y ya he terminado eso
00:19:10
significa que en esta ruta en esta ruta de aquí en esta ya está mi pdf el de descarga lo descargará
00:19:16
y listo, vale, y ya está, entonces voy a volver a comentar lo que tenía esto, entonces es el otro proyecto cambiando esta llamada y haciendo este método, vale,
00:19:32
Luego la plantilla, la plantilla, pues una plantilla corriendo rápida, que, una plantilla que era esta yo creo, vale, en esta plantilla he creado, como iba a toda velocidad, pues he creado los tres campos, equipo, corredor, puntos, los he arrastrado, equipo, corredor, puntos y ya está.
00:20:02
Y no he hecho más en la plantilla
00:20:32
Él me ha creado automáticamente estos textos estáticos
00:20:33
Los he arrastrado, lo he compilado
00:20:36
Ha compilado, he llevado el Jasper compilado
00:20:38
Al otro sitio y se acabó
00:20:40
Y ya está
00:20:42
Y ahora ejecuto esto
00:20:45
Para ver si realmente
00:20:48
Bueno, lo que sí que es cierto es que
00:20:49
Unos cuantos limpias
00:20:54
Tuvo que hacer, porque cuando tú vas haciendo
00:20:57
Copias y pegas de otro proyecto
00:20:58
Pues al final se te quedan un montón de clases
00:21:00
compiladas, otras no, entonces
00:21:02
clean todo el rato, cada vez que algo fallaba
00:21:05
clean y se arreglaba, y ya está
00:21:07
y ahora ya
00:21:09
tenemos
00:21:13
seleccionamos
00:21:14
archivo, hay que pasar un JSON
00:21:21
de
00:21:23
fórmula 1, que el JSON de
00:21:25
fórmula 1 estaba
00:21:27
en el escritorio, ahí
00:21:29
un JSON con ese modelo, claro
00:21:31
lo subimos
00:21:33
todo este rato que ha tardado se supone que se ha dado de convertirlo y ahora lo
00:21:36
descargo y este es el pdf que me ha generado muy feo porque mi plantilla ni
00:21:43
la he tocado ni la he retocado ni he hecho nada con ella
00:21:53
vale pues entonces problemas que os habéis bueno tenemos que ver ahora como
00:21:56
lo has hecho tú vale problemas que os habéis encontrado haciendo esto
00:22:04
- Materias:
- Programación
- Niveles educativos:
- ▼ Mostrar / ocultar niveles
- Formación Profesional
- Ciclo formativo de grado superior
- Segundo Curso
- Subido por:
- Raquel G.
- Licencia:
- Todos los derechos reservados
- Visualizaciones:
- 10
- Fecha:
- 18 de noviembre de 2025 - 14:01
- Visibilidad:
- Clave
- Centro:
- IES ROSA CHACEL
- Duración:
- 22′ 13″
- Relación de aspecto:
- 1.78:1
- Resolución:
- 1920x1080 píxeles
- Tamaño:
- 105.21 MBytes